Xslt 基于任何属性的值获取数据
给定一个节点,例如Xslt 基于任何属性的值获取数据,xslt,xslt-1.0,Xslt,Xslt 1.0,给定一个节点,例如 <SI elem1="TI" elem2="FN" elem3="4099450222" elem4="TM" elem5="4094110000" elem6="MT" elem7="SP" elem8="MC" elem9="DS" elem10="DA" elem11="16"/> 如果任何属性为“DA”,我需要输出为“DA”,如果任何属性为“BA”,则需要下一个属性的值(即如果elem7=“BA elem8=“03”,我需要“03”输出) 不存在多个
<SI elem1="TI" elem2="FN" elem3="4099450222" elem4="TM" elem5="4094110000" elem6="MT" elem7="SP" elem8="MC" elem9="DS" elem10="DA" elem11="16"/>
如果任何属性为“DA”,我需要输出为“DA”,如果任何属性为“BA”,则需要下一个属性的值(即如果elem7=“BA elem8=“03”,我需要“03”输出)
不存在多个匹配的危险,因此如果属性为“BA”,则不会有“DA”属性,但这些值可能出现在任何元素中
我已经研究了attribute::标记,但我不确定这是否能满足我的需要
非常感谢您的帮助我假设您的属性具有元素形式的名称,其中N=1,2,3…, 并据此订购 以下XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" />
<xsl:template match="/SI">
<xsl:choose>
<xsl:when test="some $i in @* satisfies $i='DA'">
<xsl:text>DA</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="attr" select="concat('elem', xs:decimal(substring-after(@*[.='BA']/name(), 'elem')) + 1)" />
<xsl:value-of select="@*[name() = $attr]" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
将03
作为输出
编辑
以下是XSLT1.0版本(在Altova XMLSpy下测试):
DA
如果任何属性为“DA”,我需要输出为“DA”,或者
下一个属性(如果有任何属性)是“BA”(即if elem7=“BA
elem8=“03”我想要“03”输出)
不存在多次匹配的危险,因此如果属性为“BA”,
没有“DA”属性,但这些值可以出现在任何
元素
这个XPath表达式生成所需的值:
string(/*/@*[. = 'DA']
|
/*/@*[name()
=
concat('elem', substring-after(name(/*/@*[.='BA']), 'elem') +1)]
)
03
DA
下面是完整的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:copy-of select=
"string(/*/@*[. = 'DA']
|
/*/@*[name()
=
concat('elem', substring-after(name(/*/@*[.='BA']), 'elem') +1)]
)"/>
</xsl:template>
</xsl:stylesheet>
<SI elem1="TI"
elem2="FN"
elem3="4099450222"
elem4="TM"
elem5="4094110000"
elem6="MT"
elem7="BA"
elem8="03"
elem9="DS"
elem10="DD"
elem11="16"/>
<SI elem1="TI"
elem2="FN"
elem3="4099450222"
elem4="TM"
elem5="4094110000"
elem6="MT"
elem7="SP"
elem8="MC"
elem9="DS"
elem10="DA"
elem11="16"/>
在最初提供的XML文档上应用相同的转换时(第一种情况):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:copy-of select=
"string(/*/@*[. = 'DA']
|
/*/@*[name()
=
concat('elem', substring-after(name(/*/@*[.='BA']), 'elem') +1)]
)"/>
</xsl:template>
</xsl:stylesheet>
<SI elem1="TI"
elem2="FN"
elem3="4099450222"
elem4="TM"
elem5="4094110000"
elem6="MT"
elem7="BA"
elem8="03"
elem9="DS"
elem10="DD"
elem11="16"/>
<SI elem1="TI"
elem2="FN"
elem3="4099450222"
elem4="TM"
elem5="4094110000"
elem6="MT"
elem7="SP"
elem8="MC"
elem9="DS"
elem10="DA"
elem11="16"/>
说明:
string(/*/@*[. = 'DA']
|
/*/@*[name()
=
concat('elem', substring-after(name(/*/@*[.='BA']), 'elem') +1)]
)
03
DA
正确使用XPath联合运算符
|
,以及函数string()
,substring-after()
,name()
和`concat()
Hmm,依赖于输入XML中属性的顺序通常是不稳定的。看见在任何情况下,我都不相信XSL检查预处理节点的轴可以应用于属性。属性名称将始终是elem1、elem2等。是否有方法获取属性名称,然后替换末尾的数字字符?要获取节点或属性的名称,请使用name()
@Jaloopa可以在XPATH方法之后使用子字符串来完成。请看我的答案。因为它解决了问题而被接受,我发现它比下面@dimitre的答案更可读,但我设法进入了生成XML的C代码,并设置了一个更容易获得的属性。这是否依赖于2.0版?在1.0样式表中尝试变量时,我得到以下错误:预期的标记“'),找到“(”..(子字符串在(@*[.='TM']]/name-->(@Jaloopa:正如您在样式表标题中看到的,它是用于XSLT 2.0的。您没有提到您想要XSLT 1.0解决方案…@LukaszBaran:您的也很好。我个人更喜欢避免任何条件指令。+1。