Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何计算XSLT中的节点数?_Xml_Xslt - Fatal编程技术网

Xml 如何计算XSLT中的节点数?

Xml 如何计算XSLT中的节点数?,xml,xslt,Xml,Xslt,现在进入XSL样式表的最后一步,需要输出一个表示添加的节点总数的数字。事实上,这对我来说似乎并不那么直截了当: 首先,我不是在计算原始xml文档中的节点,而是在计算结果xml中的某些节点(初始xml文档可能为空) 第二,我没有计算所有的节点 例如,下面是我的一段XSLT代码: <xsl:template name="Loop2000A"> <Loop2000A> <HL> <HL01> <xsl:value-of select

现在进入XSL样式表的最后一步,需要输出一个表示添加的节点总数的数字。事实上,这对我来说似乎并不那么直截了当:

首先,我不是在计算原始xml文档中的节点,而是在计算结果xml中的某些节点(初始xml文档可能为空)

第二,我没有计算所有的节点

例如,下面是我的一段XSLT代码:

<xsl:template name="Loop2000A">
  <Loop2000A>
<HL>
  <HL01>
    <xsl:value-of select="'1'"/>
  </HL01>
  <HL03>
    <xsl:value-of select="'20'"/>
  </HL03>
</HL>
 <xsl:if test="$recbat//provider_taxonomy_qual !='' ">
<PRV>
 <PRV01>
   <xsl:value-of select="'BI'"/>
 </PRV01>
     <PRV02>
   <xsl:value-of select="$recbat//provider_taxonomy_qual"/>
 </PRV02>
<PRV03>
   <xsl:value-of select="$recbat//provider_taxonomy"/>
</PRV03>
   </PRV>
  </xsl:if>
<xsl:call-template name="Loop2010AA"/>

对于这段代码,和被称为段,$recbat等是数据源。所以我想计算的是这些段的数量,它可以跨越不同的模板(比如上面的“Loop2010AA”模板,这是另一个模板),这些段可能有循环,所以它们可能连续创建3次,我们的计数器应该相应地递增3,或者“if”语句失败,因此,不会创建这样的段,那么计数器应该保持不变

我不确定实现这一点的正确方法,因为我在谷歌上搜索的大部分教程都是关于计算原始XML文档中的节点。我现在的一个想法是使用参数传递,但我不知道如何使这个参数成为全局参数


或者,我正在考虑一种更直接的方法。除了使用计数器变量,是否有任何方法可以先生成输出xml文档,然后计算此xml中所需的节点数,然后生成包含数字的真实输出。

以下是处理转换结果的一般方法,包括计算其节点数。

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

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
   <top>
    <xsl:apply-templates select="*"/>
    <xsl:apply-templates select="*"/>
   </top>
  </xsl:variable>

  <xsl:variable name="vPass2" select="ext:node-set($vrtfPass1)"/>

  <xsl:value-of select="count($vPass2/*/*/*)"/>
 </xsl:template>
</xsl:stylesheet>
<nums>
 <num>1</num>
 <num>2</num>
 <num>3</num>
 <num>4</num>
 <num>5</num>
</nums>
10

在XSLT 1.0(仅限)中,在多过程处理中通常需要使用
xxx:node-set()
扩展函数。XSLT2.0中没有这样的要求,它消除了臭名昭著的RTF“数据类型”。

有了完整的样式表,就可以使用适当的功能性
扫描模式对其进行重构。如果没有样式表,我只能建议进行两阶段转换:将所有内容输出到一个变量中,然后对节点进行计数。@Alejandro:实际上,我已经准备好了所有样式表,并使用(“调用模板”)将它们链接在一起。那么,我应该研究扫描模式吗?好问题,+1。有关完整的解决方案,请参见我的答案。:)@Dititre:答案很好,但“vrtfPass1”代表什么?@Robert:“v”表示变量,“rtf”是臭名昭著的类型rtf(结果树片段),这就是变量的类型。“Pass1”表示变量包含转换的Pass1结果。