【问题标题】:有没有办法在同一个 XSL 中计算 XSL 生成的元素?
【发布时间】:2022-01-19 23:55:32
【问题描述】:

如果我有一个像这个简单/粗略的例子一样创建输出的 XSL:

<Parent1>
  <ABC><xsl:value-of select="SomeValue1"/></ABC>
  <DEF><xsl:value-of select="SomeValue2"/></DEF>
  <GHI><xsl:value-of select="SomeValue3"/></GHI>
  ... 
  <YZ><xsl:value-of select="SomeValue9"/></YZ>
</Parent1>

...在同一个 XSL 中,我如何计算 XSL 将产生多少个孩子?

【问题讨论】:

标签: xslt xslt-1.0 xslt-2.0


【解决方案1】:

您的选择是:

(a) 找到一种将结果计算为输入函数的方法

(b) 捕获变量中的输出并针对该变量运行第二阶段的处理。

(c) 上述的混合:在一个变量中计算一些中间结果,并将该变量用作两个进程的输入。

在您给出的示例中,第一种方法效果很好;但我想你真正的问题比这更复杂,否则你不会问。

【讨论】:

  • 而且,应该补充一点,(a) 比 (b) 或 (c) 更可取 - 这就是为什么在确定 (a) 是否不可能之前不应建议 (b)可行的。
  • 在许多情况下 (c) 是最好的。例如,&lt;xsl:variable name="selected-items" select="items[--predicate--]"/&gt;&lt;xsl:apply-templates select="$selected-items"/&gt;&lt;xsl:value-of select="count($selected-items)"/&gt;
  • 我同意。我的意思是,我们不知道这里的情况。
【解决方案2】:

一种可能性是将整个输出过程包装在一个变量中,然后计算其后代。
因此,例如,您可以使用以下 XSLT 代码

<xsl:template match="/Parent1">
    <xsl:variable name="output">
        <ABC><xsl:value-of select="SomeValue1"/><ZZZ>Some Grandchild</ZZZ></ABC>
        <DEF><xsl:value-of select="SomeValue2"/></DEF>
        <GHI><xsl:value-of select="SomeValue3"/></GHI>
        ... 
        <YZ><xsl:value-of select="SomeValue9"/></YZ>
    </xsl:variable>
    <xsl:value-of select="concat('Outputting ', count($output/descendant::*), ' elements.&#xa;')" />
    <xsl:copy-of select="$output" />
</xsl:template>

它的输出是

Outputting 5 elements.
<ABC>
    <ZZZ>Some Grandchild</ZZZ>
</ABC>
<DEF/>
<GHI/>
... 
<YZ/>

这段代码完成了三件事:

  1. 首先它生成结果并将其放入变量中

  2. 所有的都算

    • 儿童(child::* 轴)或
    • 如上例中的后代(descendant::*轴)

    变量中的元素

  3. 将变量复制到输出流

这种方法甚至可以嵌套——这意味着它可以多次应用,一个接一个。

【讨论】:

    【解决方案3】:

    您可以将您的内容生成到一个变量中,计算变量中的子项,然后发出该变量的内容:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        
        <xsl:template match="/">
            <xsl:variable name="temp-results">
                <Parent1>
                    <ABC><xsl:value-of select="SomeValue1"/></ABC>
                    <DEF><xsl:value-of select="SomeValue2"/></DEF>
                    <GHI><xsl:value-of select="SomeValue3"/></GHI>
                    ... 
                    <YZ><xsl:value-of select="SomeValue9"/></YZ>
                </Parent1>
            </xsl:variable>
            
            <xsl:text>Number of children:</xsl:text>
            <xsl:value-of select="count($temp-results/Parent1/*)"/>
            <xsl:sequence select="$temp-results"/>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 通过选择此作为“答案”,我并不是在建议其他任何人的解决方案,反馈也不是一个好的解决方案。我首先尝试了这个,它解决了我的问题。我感谢大家在这里帮助我的贡献。谢谢!
    • 但至少为了他人的利益,如果不是你的,应该注意这可能不是最好的解决方案。由于您没有按照我的建议发布 minimal reproducible example,因此我们无法确定您的情况 - 但在大多数情况下,这是对内存和 CPU 周期的不必要浪费。
    猜你喜欢
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多