在 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>
使用 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>
.
我试过了没用...
<?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>