【问题标题】:finding maximum depth of chapter找到章节的最大深度
【发布时间】:2011-05-12 01:27:42
【问题描述】:

每个人。在这种情况下,我想计算章节的最大深度。例如,没有章节的书的高度为 0 。一本书只有章节没有章节,高度应该是1。以下是xml:

<book title="D">
<author>
  <name>abc</name>
</author>

<chapter title="chapter1">
  <section title="section1.1"/>
  <section title="section1.2">
    <section title="section1.2.1"/>
<section title="section1.2.2"/>
  </section>
  <section title="section1.3">
<section title="section1.3.1"/>
  </section>
</chapter>

<chapter title="chapter2"/>

</book>

顺便说一句,我用的是撒克逊语。我想尝试只使用匹配的模板。在这种情况下,输出是文本,结果是

 3

这是我用于计算每个音符深度的 XSL?是吗?那么如何通过调用一个名为max的模板来输出当前的最大值?

<xsl:transform version="2.0"
           xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/">
    <xsl:apply-templates select="book"/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="book">
    <xsl:apply-templates select="chapter">
        <xsl:with-param name ="depth" select ="1"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="chapter|section">
    <xsl:param name="depth"  as="item()*"/>
    <xsl:variable name ="current" select ="$depth"/>
    <xsl:sequence select ="$depth"/>
    <xsl:if test ="not(empty(section))">
        <xsl:apply-templates select="section">
            <xsl:with-param name="depth" select="$depth+1"/>
        </xsl:apply-templates>

    </xsl:if>
 </xsl:template>
</xsl:transform >

【问题讨论】:

  • 哦,谁能帮帮我??请...
  • 我不明白您想要生成的 exact 输出是什么。请说明。
  • 好问题,+1。请参阅我的答案以获得完整、简短且简单的单行 XPath 2.0 解决方案。 :)

标签: xslt xslt-2.0 max depth xpath-2.0


【解决方案1】:

XSLT 1.0 解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
     <xsl:apply-templates select="//*[self::chapter or self::section]">
       <xsl:sort data-type="number" order="descending" select=
        "count(ancestor::*[self::chapter or self::section])
        "/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="chapter|section">
    <xsl:if test="position()=1">
     <xsl:value-of select=
     "count(ancestor::*[self::chapter or self::section]) +1
     "/>
    </xsl:if>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<book title="D">
    <author>
        <name>abc</name>
    </author>
    <chapter title="chapter1">
        <section title="section1.1"/>
        <section title="section1.2">
            <section title="section1.2.1"/>
            <section title="section1.2.2"/></section>
        <section title="section1.3">
            <section title="section1.3.1"/></section>
    </chapter>
    <chapter title="chapter2"/>
</book>

产生了想要的正确答案:

3

【讨论】:

  • 谢谢。现在,我想你已经知道这个问题了吗?
  • @ZAWD:我提供了两种不同的解决方案,可以完全解决您的问题。请考虑接受和投票。
【解决方案2】:

这是您的解决方案 -- 已更正

<xsl:transform version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text" encoding="UTF-8"/>

 <xsl:template match="/">
  <xsl:variable name="vDepths" as="xs:integer*">
   <xsl:apply-templates select="book"/>
  </xsl:variable>

  <xsl:sequence select="max($vDepths)"/>
 </xsl:template>

 <xsl:template match="book" as="xs:integer*">
  <xsl:apply-templates select="chapter">
   <xsl:with-param name ="depth" select ="1"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="chapter|section" as="xs:integer*">
  <xsl:param name="depth"  as="xs:integer"/>
  <xsl:variable name ="current" select ="$depth"/>

  <xsl:sequence select ="$depth"/>
  <xsl:if test ="not(empty(section))">
   <xsl:apply-templates select="section">
    <xsl:with-param name="depth" select="$depth+1"/>
   </xsl:apply-templates>
  </xsl:if>
 </xsl:template>
</xsl:transform >

【讨论】:

    【解决方案3】:

    使用

    max(//(chapter|section)/count(ancestor::*[self::chapter or self::section]))+1
    

    这可以稍微提高效率

    max(//(chapter|section)[not(chapter or section)]
                /count(ancestor::*[self::chapter or self::section])
        ) +1
    

    【讨论】:

    • @Dimitre Novatchev:谢谢。现在,我想你已经知道这个问题了?如果我想输出每个音符的章节深度,我的 xsl 有问题吗?我的意思是,例如,chapter1->"1",section1.1->"2",section1.2->"2",section1.2.1->"3" ......所以我的xsl的输出是1 2 2 3 3 2 3 1.现在,我想要的是结合模板马赫和最大模板(可以选择这个序列的最大数量“1 2 2 3 3 2 3 1”)
    • @ZAWD:我在单独的答案中提供了对您的解决方案的更正。
    • @Dimitre Novatchev:是的,你确实给了我一个很好的答案。但我不想使用 ,只是使用名为 max(或其他名称)的模板,调用它以找到最大剂量。它会起作用吗?
    • @ZAWD:我为您提供了一个仅使用模板的 XSLT 1.0 解决方案。您可以在 XSLT 2.0 中使用相同的解决方案。
    • @ZAWD:我还在单独的答案中更正了 your 解决方案。你找到了吗?
    猜你喜欢
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2015-04-19
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    相关资源
    最近更新 更多