开发者

Reversing order without xsl:sort

There is some problem in my xsl ,I do not know the reason I want to use apply-templates to reverse the different sequences of XML without xsl:sort; For example : the following is the input

<book title="XML">
  <author first="P" />
   <chapter title="A">
     <section title="A.1" />
     <section title="A.2">
       <section title="A.2.1" />
       <section title="A.2.2" />
     </section>
     <section title="A.3">
       <section title="A.3.1" />
    </section>
  </chapter>
  <chapter title="B">
    <section title="B.1" />
    <section title="B.2">
      <section title="B.2.1" />
      <section title="B.2.2" />
    </section>
  </chapter>
</book>

I want to get the output like this:this is my xsl.

<?xml version="1.0" encoding="UTF-8"?>
<book title="XML">
   <author first="P"/>
   <chapter title="A">
      <section title="A.1">
        <section title="A.3.1"/>
      </section>
      <section title="A.2">
        <section title="A.2.2"/>
        <section title="A.2.1"/>
      </section>
      <section title="A.1"/>
   </chapter>
   <chapter title="B">
      <section title="B.2">
         <section title="B.2.2"/>
         <section title="B.2.1"/>
      </section>
      <section title="B.1"/>
   </chapter>
  </book>

Yes,the sections have been reversed but the chapters are not. the following is my xsl ,there is some problem here ,could you help me to find it??

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
  <xsl:output method="xml"  version="1.0" encoding="UTF-8" indent ="yes"/>
  <xsl:template match="/">
    <xsl:apply-templates/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="book">
    <xsl:copy>
      <xsl:sequence select="@title"/>
      <xsl:sequence select="author"/>
      <xsl:apply-templates select="chapter">
        <xsl:with-param name="seq" select="section"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match ="chapter|section" as="element()">
    <xsl:param name="seq" as="element(section)*"/>
    <xsl:copy>
         <xsl:sequence select="@title"/>
        <xsl:if test="not(empty($seq))">
             <xsl:apply-templates select="chapter">
                <xsl:with-param name="seq" select="$seq"/>
            </xsl:apply-templates>
            <xsl:apply-templates select="$seq[1]"/>
        </xsl:if>
    </xsl:copy>
 开发者_如何学Go </xsl:template>
</xsl:transform>


This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="section">
        <xsl:apply-templates select="following-sibling::node()[1]"/>
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Output:

<book title="XML">
    <author first="P"></author>
    <chapter title="A ">
        <section title="A.3 ">
            <section title="A.3.1"></section>
        </section>
        <section title="A.2">
            <section title="A.2.2"></section>
            <section title="A.2.1"></section>
        </section>
        <section title="A.1"></section>
    </chapter>
    <chapter title="B">
        <section title="B.2">
            <section title="B.2.2"></section>
            <section title="B.2.1"></section>
        </section>
        <section title="B.1"></section>
    </chapter>
</book>


How about this?

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

  <xsl:template match ="chapter|section">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:for-each select="*">
            <xsl:sort select="position()" data-type="number" order="descending"/>
            <xsl:apply-templates select="." />
        </xsl:for-each>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:transform>

A couple of things to note:

  • match="*" template: This provides a default behavior for elements that we just need to copy with attributes and then process the children. This replaces your "book" and "/" templates and doesn't make assumptions about what elements are in it. This means we now can focus on providing template(s) for elements that are not covered by default behavior.
  • for-each: This is where the magic happens by enumerating the children which we then sort in descending order based on position before processing them with apply templates.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜