XSLT for-each 循环遍历 2 个具有相同名称但不同属性的元素

XSLT for-each loop iterating through 2 elements with same name but different attribute

注意:解决方案应为 XSLt 1.0

我是 XSLT 的完全新手,如果与循环相关的其他问题的解决方案可以解决我的问题,我深表歉意,但到目前为止我运气不好。

我有一个包含多个节点的 XML 文件,如下所示:

<Roles>
  <field name="linecode" instance="1" value="EY"/>
  <field name="number" instance="1" value="265"/>
  <field name="linecode" instance="2" value="PK"/>
  <field name="number" instance="2" value="123"/>
  <field name="abc" instance="1" value="123"/>
  <field name="xyz" instance="1" value="123"/>
</Role>

我需要遍历这些节点并打印 <field name="linecode"> 及其匹配实例编号 <field name="number">。但是,如果我使用 for-each 循环,它将遍历 <field name="linecode">s 正常但打印相同的 <field name="number"> 不起作用。

有什么方法可以让它们同步,例如输出会是

EY - 265
PK - 123

我也曾尝试使用 following-sibling,但它对我不起作用。非常感谢任何帮助。 .

这是我的示例 xslt。

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

<xsl:template match="Roles">
    <xsl:for-each select="field[@name='linecode']">
        <xsl:value-of select="@value"/>
        <xsl:text> - </xsl:text>
        <xsl:value-of select="field[@name='number' and instance='@instance']"/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
</xsl:template>

如果有人能想到一种替代循环的方法,我将不胜感激。

你要的表情是这样的..

<xsl:value-of select="../field[@name='number' and @instance=current()/@instance]/@value"/>

注意开头使用 ../。如果您只是 <xsl:value-of select="field.." /> ,那么当您已经位于 field 元素上时,您将尝试 select 一个名为 field 的子元素。首先对父节点执行 .. select,允许您 select 一个兄弟元素。

还要注意 current() 的使用,它指的是您当前所在的节点(您 select 和 xsl:for-each 所在的节点)。在此处阅读 "current node vs context node":Current node vs. Context node in XSLT/XPath?

或者,您可以在此处了解如何使用密钥。您可以定义一个键来通过 instance 属性

查找 field 元素
<xsl:key name="fields" match="field" use="@instance" />

因此,要查找您执行此操作的元素..

<xsl:value-of select="key('fields', @instance)[@name = 'number']/@value"/>

也试试这个 XSLT

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

<xsl:key name="fields" match="field" use="@instance" />

<xsl:template match="Roles">
    <xsl:for-each select="field[@name='linecode']">
        <xsl:value-of select="@value"/>
        <xsl:text> - </xsl:text>
        <xsl:value-of select="key('fields', @instance)[@name = 'number']/@value"/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<xsl:template match="Roles">
        <xsl:for-each select="field">
            <xsl:if test="@name='linecode'">
            <xsl:value-of select="@value"/>
                <xsl:text> - </xsl:text>
            </xsl:if>

            <xsl:if test="@name='number'">
                <xsl:value-of select="@value"/>
                <xsl:text>&#xa;</xsl:text>
            </xsl:if>

        </xsl:for-each>
Also try it

如果 "matching instance" 是指紧随其后的字段元素,则可以使用

<xsl:value-of select="following-sibling::field[1]/@value"/>

但如果"matching instance"表示相同id的数字字段,则使用

<xsl:value-of select="../field[@name='number' and @instance=current()/@instance]/@value"/>