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> </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.
精彩评论