2012-11-23 133 views
4

我是XSLT新手,所以这可能是非常基本的,但我真的很感激一些输入。我需要在我的xml中转换子节点,但同时保持父节点不变。我的XML看起来是这样的:XSLT:如何复制父节点并转换子节点

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data"> 
    <result form="10" version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462"> 
     <Q0061 answerid="1">1</Q0061> 
     <Q0060 answerid="2">2</Q0060> 
     <QTXT1>1</QTXT1> 
    </result> 
</XMLTest> 

我需要保持两个顶级节点的XMLTest和结果不变,而子节点需要被转化为一个更通用的格式是这样的:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data"> 
    <result form="10" version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462"> 
     <answer>Q0061</answer> 
     <id>1</id> 
     <value>1</value> 
     <answer>Q0060</answer> 
     <id>2</id> 
     <value>2</value> 
     <answer>QTXT1</answer> 
     <value>1</value> 
    </result> 
</XMLTest> 

我XSLT到目前为止是这样的:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 

    <xsl:template match="result/*"> 
     <answer><xsl:value-of select="local-name()"/></answer> 
     <id><xsl:value-of select="@answerid"/></id> 
     <value><xsl:value-of select="@*"/></value> 
    </xsl:template> 
</xsl:stylesheet> 

我使用XSL尝试:复制顶部节点上,但不能让它不失子节点,或子节点的改造工作。如何保持顶层节点并同时通过我的转换后的子节点进行强制操作?

+0

不错尝试upvoted!只是你缺少身份模板哪些副本休息其他节点..检查我的答案.. –

+0

我已经更新了答案与评论..请检查它.. –

回答

2

开始

<xsl:template match="@* | node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

现在,添加模板供您需要即

012改造
+0

哦,他不需要一个空白节点,如果没有属性..! +1 –

+0

粉碎 - 这很有效!谢谢 :-) – Chrissy

1

你缺少身份模板:

<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

我已经改正你回答..:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="/XMLTest/result/*"> 
    <answer> 
     <xsl:value-of select="local-name()"/> 
    </answer> 
    <id> 
     <xsl:value-of select="@answerid"/> 
    </id> 
    <value> 
     <xsl:value-of select="@*"/> 
    </value> 
    </xsl:template> 


</xsl:stylesheet> 

EDIT1: 更新的模板丢弃,如果属性是空的:一个if条件检查如果在将其转换为元素之前属性为null ..

<xsl:template match="/XMLTest/result/*"> 
    <answer> 
     <xsl:value-of select="local-name()"/> 
    </answer> 
    <xsl:if test="@answerid/.!=''"> 
     <id> 
     <xsl:value-of select="@answerid"/> 
    </id> 
    </xsl:if> 
    <xsl:if test="@*/.!=''"> 
    <value> 
     <xsl:value-of select="@*"/> 
    </value> 
    </xsl:if> 
    </xsl:template> 

编辑2:在您的早期尝试中,您试图复制@ *的值,@*指示任何名称的属性,所以它正在复制@answerid的值(因为这是唯一可用的属性)。做的是.. valu-of="." ..请尝试下面的代码..

<xsl:template match="/XMLTest/result/*"> 
    <answer> 
     <xsl:value-of select="local-name()"/> 
    </answer> 
    <xsl:if test="@answerid/.!=''"> 
     <id> 
     <xsl:value-of select="@answerid"/> 
    </id> 
    </xsl:if> 
    <xsl:if test=".!=''"> 
    <value> 
     <xsl:value-of select="."/> 
    </value> 
    </xsl:if> 
    </xsl:template> 
+0

谢谢,这解决了我的问题!只是一个细节仍然不正确的代码。如果子节点缺少answerid属性,则标记值不会被填充。我如何正确编码?我得到的是: QTXT1。 – Chrissy

+0

很高兴知道..是的它是什么?请去头 –

+0

只是更新了我以前的评论那里 – Chrissy