在XSL转换期间维护XML注释

时间:2013-07-17 15:24:54

标签: xml xslt xslt-1.0

XML

<?xml-stylesheet type="text/xsl" href="script.xsl"?>
<elements>
  <stack>
    <name>Ray</name>
    <status>0</status>
  </stack>
<!-- Comment 1 -->
  <things>
  <!-- Comment 2 -->
    <thing>
      <color>red</color>
      <!-- State Comment -->
      <state>solid</state>
      <!-- Weight Comment -->
      <weight>45</weight>
      <unit>34</unit>
      <!-- Comment 3 -->
    </thing>
 </things>
 <favs>
   <stick>ready</stick>
   <!-- Comment 4-->
 </favs>
</elements>

预期输出

<elements>
  <stack>
    <name>Ray</name>
    <status>0</status>
  </stack>
  <!-- Comment 1 -->
  <mainElements>
  <!-- Comment 2 -->
    <specialThing>
      <!-- Weight Comment -->
      <PropertyOne>45</PropertyOne>
      <PropertyTwo>red</PropertyTwo>
      <!-- State Comment -->
      <PropertyThree>solid</PropertyThree>
    </specialThing>
  <!-- Comment 3 -->
  </mainElements>
 <favs>
     <stick>ready</stick>
     <!-- Comment 4-->
 </favs>
</elements>

CURRENT XSL

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

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


<xsl:template match="things">
        <mainElements>
            <xsl:apply-templates select="thing"/>
        </mainElements>
    </xsl:template>


<xsl:template match="thing">
    <specialThing>
        <xsl:apply-templates select="weight"/>
    <xsl:apply-templates select="color"/>
    <xsl:apply-templates select="state"/>
        </specialThing>
</xsl:template>


<xsl:template match="weight">
    <PropertyOne>
       <xsl:value-of select="."/>
       </PropertyOne>
</xsl:template>

<xsl:template match="color">
    <PropertyTwo>
       <xsl:value-of select="."/>
        </PropertyTwo>
</xsl:template>

<xsl:template match="state">
    <PropertyThree>
       <xsl:value-of select="."/>
        </PropertyThree>
</xsl:template>
</xsl:stylesheet>

我无法正确缩进输出,就像我在输出中提到的那样。 但我想要实现的主要目的是维护输出中保留的标记的注释。

例如:名为weight的标签重命名为“PropertyOne”,并且该值也在输出中保留。但是上面的评论却缺失了。我想在输出中保留相同的注释。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

您必须为前一个兄弟xsl:apply-templates执行comment()。由于您要更改weight / color / state的顺序,因此您必须将其添加到每个模板中。

此外,匹配Comment 3很棘手,我所做的可能对您的实际数据不起作用。

XML输入

<elements>
    <stack>
        <name>Ray</name>
        <status>0</status>
    </stack>
    <!-- Comment 1 -->
    <things>
        <!-- Comment 2 -->
        <thing>
            <color>red</color>
            <!-- State Comment -->
            <state>solid</state>
            <!-- Weight Comment 1 -->
            <!-- Weight Comment 2 -->
            <weight>45</weight>
            <unit>34</unit>
            <!-- Comment 3 -->
        </thing>
    </things>
    <favs>
        <stick>ready</stick>
        <!-- Comment 4-->
    </favs>
</elements>

XSLT 1.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

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


    <xsl:template match="things">
        <mainElements>
            <xsl:apply-templates select="thing|comment()"/>
        </mainElements>
    </xsl:template>


    <xsl:template match="thing">
        <specialThing>
            <xsl:apply-templates select="weight"/>
            <xsl:apply-templates select="color"/>
            <xsl:apply-templates select="state"/>           
        </specialThing>
        <xsl:apply-templates select="comment()[not(following-sibling::*)]"/>
    </xsl:template>


    <xsl:template match="weight">
        <xsl:apply-templates select="preceding-sibling::comment()[generate-id(following-sibling::*[1])=generate-id(current())]"/>
        <PropertyOne>
            <xsl:value-of select="."/>
        </PropertyOne>
    </xsl:template>

    <xsl:template match="color">
        <xsl:apply-templates select="preceding-sibling::comment()[generate-id(following-sibling::*[1])=generate-id(current())]"/>
        <PropertyTwo>
            <xsl:value-of select="."/>
        </PropertyTwo>
    </xsl:template>

    <xsl:template match="state">
        <xsl:apply-templates select="preceding-sibling::comment()[generate-id(following-sibling::*[1])=generate-id(current())]"/>
        <PropertyThree>
            <xsl:value-of select="."/>
        </PropertyThree>
    </xsl:template>

</xsl:stylesheet>

XML输出

<elements>
    <stack>
        <name>Ray</name>
        <status>0</status>
    </stack>
    <!-- Comment 1 -->
    <mainElements>
        <!-- Comment 2 -->
        <specialThing>
            <!-- Weight Comment 1 -->
            <!-- Weight Comment 2 -->
            <PropertyOne>45</PropertyOne>
            <PropertyTwo>red</PropertyTwo>
            <!-- State Comment -->
            <PropertyThree>solid</PropertyThree>
        </specialThing>
        <!-- Comment 3 -->
    </mainElements>
    <favs>
        <stick>ready</stick>
        <!-- Comment 4-->
    </favs>
</elements>