在 XSL 中,当另一个元素的兄弟元素的属性为某个值时,我如何 return 另一个元素?

In XSL, how can I return another element when its sibling element's attribute is a certain value?

使用 XML 输入如:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <loop Id="N1">
        <segment Id="N1">
            <element Id="N101">BT</element>
            <element Id="N102">JOHN'S PIZZA</element>
            <element Id="N103">92</element>
            <element Id="N104">910</element>
        </segment>
    </loop>
</root>

...当 <element Id="N101">BT</element> 存在时,我试图从其相关兄弟 <element Id="N102">JOHN'S PIZZA</element>.

中获取值“JOHN'S PIZZA”

我试过了没用...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output indent="yes"/>
    <xsl:template match="/root">
        <xsl:choose>
            <xsl:when test="loop[@Id = 'N1']/segment[@Id = 'N1']/element[@Id = 'N101'] = 'BT'">
                <BillTo>
                    <Name xml:lang="en-US">
                        <xsl:value-of select="../element[@Id = 'N102']"/>
                    </Name>
                </BillTo>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

...因为它没有 return 任何值:

<?xml version="1.0" encoding="UTF-8"?>
<BillTo>
   <Name xml:lang="en-US"/>
</BillTo>

后续问题...

当其他 <element Id="N201"> 元素位于 <element Id="N101">BT</element> 存在的相同 loop[@Id = 'N1'] 中时,我如何也 return 这些元素?

<root>
    <loop Id="N1">
        <segment Id="N1">
            <element Id="N101">BT</element>
            <element Id="N102">JOHN'S PIZZA</element>
            <element Id="N103">92</element>
            <element Id="N104">910</element>
        </segment>
  <segment Id="N2">
            <element Id="N201">SOME OTHER VALUE</element>
        </segment>
    </loop>
</root>

感谢您的帮助。

您在匹配 /root 的模板中,虽然您已经在 xsl:when 中测试了一个条件,但上下文没有改变。您仍然“站在”/root 元素上。因此,../element[@Id = 'N102'] 试图跳转到 root 的父级,然后是 select 不存在的 element

我会将 XPath 略微调整为 select 您尝试定位的 element

loop[@Id = 'N1']//segment[@Id = 'N1' and element[@Id = 'N101' and . = 'BT']]/element[@Id = 'N102']

并使用xsl:apply-templates,用模板匹配element并格式化它。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output indent="yes"/>
    <xsl:template match="/root">
        <xsl:apply-templates select="loop[@Id = 'N1']//segment[@Id = 'N1' and element[@Id = 'N101' and . = 'BT']]/element[@Id = 'N102']"/>
    </xsl:template>
    
    <xsl:template match="element">
        <BillTo>
            <Name xml:lang="en-US">
                <xsl:value-of select="."/>
            </Name>
        </BillTo>
    </xsl:template>
</xsl:stylesheet>

但您也可以使用 xsl:for-each 到 select 那个节点,然后上下文就是 selected element:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output indent="yes"/>
    <xsl:template match="/root">
        <xsl:for-each select="loop[@Id = 'N1']//segment[@Id = 'N1' and element[@Id = 'N101' and . = 'BT']]/element[@Id = 'N102']">
            <BillTo>
                <Name xml:lang="en-US">
                    <xsl:value-of select="."/>
                </Name>
                <xsl:copy-of select="preceding-sibling::* | following-sibling::*"/>
            </BillTo>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>