没有xsl:sort的逆转顺序

时间:2011-05-03 07:35:55

标签: xslt

我的xsl有一些问题,我不知道原因 我想使用apply-templates来反转不同的XML序列,而不需要xsl:sort;  例如:以下是输入

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

我想得到这样的输出:这是我的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>

是的,这些章节已被撤销,但章节却没有。 以下是我的xsl,这里有一些问题,你能帮我找到吗?

<?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>
  </xsl:template>
</xsl:transform>

2 个答案:

答案 0 :(得分:1)

此样式表:

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

输出:

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

答案 1 :(得分:0)

这个怎么样?

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

有几点需要注意:

  • match =“*”template:这为我们只需要使用属性复制然后处理子项的元素提供默认行为。这将取代您的“书籍”和“/”模板,而不会假设其中包含哪些元素。这意味着我们现在可以专注于为默认行为未涵盖的元素提供模板。
  • for-each:这是通过枚举子项来实现神奇的地方,然后我们在使用应用模板处理它们之前根据位置按降序排序。