2013-07-17 76 views
2

XMLXSL转换

<?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> 

期间维护XML注释我没能正确地缩进输出作为我在输出中提到的。 但我想实现的主要目的是维护输出中维护的标签的注释。

例如:名为weight的标签被重命名为“PropertyOne”,并且该值也在输出中维护。但是上面的评论也没有。我想在输出中保留相同的注释。我怎么能做到这一点?

回答

1

您必须为前面的兄弟comment()做一个xsl:apply-templates。由于您要更改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> 
+1

我建议改变'前同辈::评论() [1]'t (1)[self-comment()]]或prior-sibling :: comment()[count(after-sibling :: * [1] | current())= 1]'来防止模板意外地抓住另一个元素的注释。 – JLRishe

+0

@Daniel非常感谢你:) –

+0

@JLRishie Thanx for the tips bro :) :) –