Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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
Xslt 遍历/循环XSL键:如何?_Xslt_Loops_Foreach_Key - Fatal编程技术网

Xslt 遍历/循环XSL键:如何?

Xslt 遍历/循环XSL键:如何?,xslt,loops,foreach,key,Xslt,Loops,Foreach,Key,有没有办法遍历一个键并输出它包含的所有值 <xsl:key name="kElement" match="Element/Element[@idref]" use="@idref" /> 我是这样想的: <xsl:for-each select="key('kElement', '.')"> <li><xsl:value-of select="." /></li> </xsl:for-each> 然而

有没有办法遍历一个键并输出它包含的所有值

   <xsl:key name="kElement" match="Element/Element[@idref]" use="@idref" />

我是这样想的:

<xsl:for-each select="key('kElement', '.')">
  <li><xsl:value-of select="." /></li>
</xsl:for-each>

  • 然而,这是行不通的。我只想列出一个键中的所有值,以便进行测试


    问题很简单:如何做到这一点?

    你不能。那不是钥匙的用途

    当且仅当每个元素的键相同时,可以使用对
    key()
    的单个调用循环键中的每个元素

    如果需要循环定义键的所有内容,可以使用
    元素的
    match=“…”
    属性中的表达式

    如果你有这样一个文件:

    <root>
      <element name="Bill"/>
      <element name="Francis"/>
      <element name="Louis"/>
      <element name="Zoey"/>
    </root>
    
    <xsl:key name="survivors" match="element" use="@name"/>
    
    <xsl:key name="survivors" match="element" use="@class"/>
    
    <xsl:for-each select="key('survivors', 'survivor')">
      <!-- stuff -->
    </xsl:for-each>
    
    <xsl:for-each select="Element/Element[@idref]">
      <!-- stuff -->
    </xsl:for-each>
    
    或者,如果每个元素都有共同点:

    <root>
      <element name="Bill" class="survivor"/>
      <element name="Francis" class="survivor"/>
      <element name="Louis" class="survivor"/>
      <element name="Zoey" class="survivor"/>
    </root>
    
    因此,您可以像这样循环浏览它的所有内容:

    <root>
      <element name="Bill"/>
      <element name="Francis"/>
      <element name="Louis"/>
      <element name="Zoey"/>
    </root>
    
    <xsl:key name="survivors" match="element" use="@name"/>
    
    <xsl:key name="survivors" match="element" use="@class"/>
    
    <xsl:for-each select="key('survivors', 'survivor')">
      <!-- stuff -->
    </xsl:for-each>
    
    <xsl:for-each select="Element/Element[@idref]">
      <!-- stuff -->
    </xsl:for-each>
    
    
    
    您可以创建一个用于循环的键-如果您只需在key元素的use属性中指定一个常量:

    <xsl:key name="survivors" match="element" use="'all'"/>
    
    
    
    然后可以按以下方式循环所有元素:

    <xsl:for-each select="key('survivors','all')">
        ...
    </xsl:for-each>
    
    
    ...
    
    或者数一数:

    <xsl:value-of select="count(key('survivors','all'))"/>
    
    
    
    请注意,常数可以是任何字符串,甚至可以是一个数字,但“all”读起来不错

    但是,不能使用此键查找有关单个条目的信息(因为它们都具有相同的键)

    换句话说,有两种可能的键:

  • “查找键”=在“使用”属性中具有不同索引的标准键
  • “循环键”=使用属性中具有常量的键

  • 我不知道这种方法的执行效率有多高,但是它确实通过避免在整个XSL代码中重复相同(可能非常复杂)的XPath表达式而提高了XSL的维护效率。

    与其在编程语言术语中考虑XSL键,不如将它们看作SQL的记录集。这将有助于更好地理解。对于创建为的给定键索引

    <xsl:key name="paths" match="path" use="keygenerator()">
    
    使用此XSL进行转换

      <xsl:for-each select="*/Person">
      <personrecords>
           <xsl:value-of select="generate-id(.)" />--
           <xsl:value-of select="name"/>--
           <xsl:value-of select="date"/>--      
      </personrecords>
      </xsl:for-each>
    
      <xsl:for-each select="*/*/cost">
      <costrecords>
          <xsl:value-of select="generate-id(.)" />--
          <xsl:value-of select="../name"/>-- 
          <xsl:value-of select="../date"/>-- 
          <xsl:value-of select="@itemID"/>-- 
          <xsl:value-of select="text()"/>
      </costrecords>
      </xsl:for-each>
    
    让我们使用
    名称
    项目ID
    值的组合,在
    成本
    记录上创建一个键。

    
    
    手动查看XML,上面的唯一键的数量将是三个:Johny+1Johny+2Johny+3

    现在让我们使用下面的代码段来测试这个键

    
    -- 
    (1)-- 
    (2)-- 
    (3)-- 
    (4)
    
    结果如下:

    1。idp2805696——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
    2.idp4013568——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
    3.idp2808192——(1)idp2808192——(2)IDP261224——(3)idp2610432——(4)
    4.idp2808640——(1)idp2808640——(2)idp2808640——(3)idp2808640——(4)
    5.idp2609728——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
    6.idp4011648——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
    7.IDP261224——(1)idp2808192——(2)IDP261224——(3)idp2610432——(4)
    8.idp2610432——(1)idp2808192——(2)IDP261224——(3)idp2610432——(4)
    
    我们的兴趣是试图理解
    [1]
    [2]
    [3]
    [4]
    的重要性。在我们的例子中,keygenerator是
    concat(../name,“+”,@itemID)

    对于给定的密钥,
    [1]
    指满足密钥生成器的节点的第一次出现。类似地,
    [2]
    指满足keygenerator的节点的第二次出现。因此,
    [2]
    [3]
    [4]
    等都是满足相同密钥的节点,因此可以认为是给定密钥的重复节点。重复的数量取决于输入XML。因此:

    Johny+1满足4节点(1)idp2805696--(2)idp4013568--(3)idp2609728--(4)idp4011648
    Johny+2满足3节点(1)idp2808192--(2)IDP261224--(3)idp2610432--(4)
    Johny+3满足1节点(1)idp2808640--(2)--(3)--(4)

    因此,我们看到XML的所有8个
    成本
    节点都可以通过键访问

    这是一幅结合了转换结果的图像,有助于更好地理解

    红色方块表示Johny+1的匹配节点。绿色方块表示Johny+3的匹配节点。将
    中的
    idpxxxxxxx
    值与
    中的值相匹配。
    帮助将
    idpxxxxxxx
    值映射到源XML

    外卖是

    XSL键不会过滤或消除节点。所有节点(包括重复节点)都可以通过密钥访问。因此,当我们说密钥的“遍历”时,没有从原始节点集中生成节点子集的概念,这些节点可供密钥处理。

    要在上面的示例中仅“遍历”键的唯一节点,请使用

    
    
    [1]
    表示给定键值的第一条记录被表示为唯一记录<代码>[1]
    几乎总是被使用,因为至少存在一个满足给定键值的节点。如果我们确定至少有2条记录满足键中的每个键值,我们可以继续使用
    [2]
    将记录集中的第二条记录标识为唯一记录


    p.S单词nodes/records/elements可以互换使用。

    尽管我们可以输出其中包含的所有值,但无法遍历键。在XSLT2中比在XSLT1中容易(例如,根据前面的答案使用
    fn:generate id

    使用
    fn:不同的值

    <xsl:variable name="e" select="."/>
    <xsl:for-each select="distinct-values(Element/Element[@idref]/@idref)">
      <li key="{.}"><xsl:value-of select="key('kElement', ., $e )" /></li>
    </xsl:for-each>
    
    (+1)有道理。那
    <xsl:for-each-group select="Element/Element[@idref]" group-by="@idref">
      <li key="{current-grouping-key()}"><xsl:value-of select="current-group()" /></li>
    </xsl:for-each-group>