不使用 xsl:sort 反转顺序

发布于 2024-11-04 08:51:34 字数 2790 浏览 1 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

定格我的天空 2024-11-11 08:51:34

该样式表:

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

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>
北渚 2024-11-11 08:51:34

这个怎么样?

<?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="*" 模板:这为我们只需要复制属性然后处理子元素的元素提供了默认行为。这会替换您的“book”和“/”模板,并且不会假设其中包含哪些元素。这意味着我们现在可以专注于为默认行为未涵盖的元素提供模板。
  • for-each:这就是神奇的地方,通过枚举子级,然后我们根据位置按降序排序,然后再使用应用模板处理它们。

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文