XSLT将子元素作为属性带入父级并保留现有父属性

时间:2014-12-09 17:35:46

标签: xslt

我很难过,对XSLT来说很新。一点点的指示将不胜感激。我的最终目标是将student元素下的firstName,lastName和gender元素作为属性添加到该元素中,但也希望保留已存在的StudentID属性。我也喜欢那个" year_Collection"消失。



我从这个XML文档开始

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="Upload" Name="Upload">
    <student StudentID="123456">
        <firstName firstName="John"/>
        <lastName lastName="Johnson"/>
        <gender gender="M"/>
        <year_Collection>
            <year value="2013">
                <term hoursEarned="18.00" hoursAttempted="18.00" termCode="S1"/>
            </year>
        </year_Collection>
    </student>
</Report>



我想要的输出看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="Upload" Name="Upload">
    <student gender="M" lastName="Johnson" firstName="John" StudentID="123456">
        <year value="2013">
            <term hoursEarned="18.00" hoursAttempted="18.00" termCode="S1"/>
        </year>
    </student>
</Report>



我能够使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:r="Upload" exclude-result-prefixes="r" extension-element-prefixes="r">
    <xsl:template match="r:student">
      <xsl:copy>
        <xsl:for-each select="*">
          <xsl:attribute name="{local-name(.)}">
            <xsl:value-of select="."/>
          </xsl:attribute>  
          <xsl:copy-of select="@*"/>
          <xsl:apply-templates/>
        </xsl:for-each>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>   



来到这里:

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="Upload" Name="Upload">
    <student year_Collection="" gender="M" lastName="Johnson" firstName="John">
        <year value="2013">
            <term hoursEarned="18.00" hoursAttempted="18.00" termCode="S1"/>
        </year>
    </student>
</Report>



但它会覆盖已存在的StudentID属性。如何将元素作为属性出现,但不能覆盖StudentID?

另外,那个讨厌的year_collection元素不会随之消失,但我可以把它分成一个单独的问题,如果这是一个更好的方法。

<xsl:template match="r:year_Collection">
    <xsl:apply-templates/>
</xsl:template>

1 个答案:

答案 0 :(得分:1)

  

但它会覆盖已存在的StudentID属性。

不,它没有。问题是你没有复制它。您应该使用以下命令启动模板:

<xsl:template match="r:student">
    <xsl:copy>
    <xsl:copy-of select="@StudentID"/>  

或者,如果您愿意:

<xsl:template match="r:student">
    <xsl:copy>
    <xsl:copy-of select="@*"/>  

复制学生拥有的所有属性。

关于<year_Collection>的问题,您应该尝试仅将叶节点转换为属性,例如:

<xsl:template match="r:student">
    <xsl:copy>
        <xsl:copy-of select="@*"/>  
        <xsl:copy-of select="*/@*"/>  
        <xsl:copy-of select="*/*[@*]"/>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>  

当然,如果您的结构已知,那么明确命名所需节点会更好,例如

<xsl:template match="r:student">
    <xsl:copy>
        <xsl:copy-of select="@StudentID | r:firstName/@firstName | r:lastName/@lastName | r:gender/@gender"/>  
        <xsl:copy-of select="r:year_Collection/r:year"/>
    </xsl:copy>
</xsl:template>