项目的属性在@properties属性中以空格分隔的术语列出。还有一个主要的属性列表。
<t>
<items>
<item id='a' properties='red little' />
<item id='b' properties='big strong heavy' />
<item id='c' properties='blue heavy' >
</items>
<properties>
<property id='red' />
<property id='little' />
<property id='blue' />
</properties>
</t>
我的问题:使用XLST 1.0,为模板编写匹配属性,该属性将匹配属性主列表中至少有一个属性的所有项目。
项目a和c匹配。项目b不会。
这是XSLT 1.0,所以我不能使用str:split。也许有关键和contains()的东西?
答案 0 :(得分:1)
你也可以使用<xsl:if>
吗?
<xsl:template match="item">
<xsl:if test="/t/properties/property[contains(concat(' ', current()/@properties, ' '), concat(' ', @id, ' '))]">
...
</xsl:if>
</xsl:template>
不幸的是,current()
无法在match
属性中使用。
答案 1 :(得分:1)
使用Michael Liu的XPath表达式,您还可以构造一个允许您匹配正确元素的键:
<xsl:key name="inMaster" match="item" use="
substring(
'1',
1,
string-length(
/t/properties/property[
contains(concat(' ', current()/@properties, ' '), concat(' ', @id, ' '))
]/@id
)
)"/>
<!-- The following template matches the wanted item elements -->
<xsl:template match="key('inMaster','1')">
...
</xsl:template>
我们使用substring()
函数将匹配的<item>
元素与字符串"1"
相关联。所有不匹配的item元素都与空字符串相关联,因为没有匹配的“master”属性,因此没有id
属性,因此string-length()
为0,因此我们提取了一个子字符串长度为0(即空字符串)。
答案 2 :(得分:1)
<强>予。使用密钥和current()
的另一种解决方案:):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kItemByProp" match="item"
use="boolean(/*/properties/property/@id
[contains(concat(' ', current()/@properties, ' '),
.)]
)"/>
<xsl:template match=
"item[count(.| key('kItemByProp', 'true'))
=
count(key('kItemByProp', 'true'))
]
">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<t>
<items>
<item id='a' properties='red little' />
<item id='b' properties='big strong heavy' />
<item id='c' properties='blue heavy' />
</items>
<properties>
<property id='red' />
<property id='little' />
<property id='blue' />
</properties>
</t>
产生了想要的正确结果:
<item id="a" properties="red little"/>
<item id="c" properties="blue heavy"/>
<强> II。没有键,但条件指令作为模板体中的最外层:
<xsl:template match="item">
<xsl:if test=
"/*/properties/*/@id
[contains(concat(' ', current()/@properties, ' '), .)]">
<!-- Your processing here -->
</xsl:if>
</xsl:template>
这是一个完整的转型:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="item">
<xsl:if test=
"/*/properties/*/@id
[contains(concat(' ', current()/@properties, ' '), .)]">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当此转换应用于同一XML文档(上图)时,会产生相同的正确结果:
<item id="a" properties="red little"/>
<item id="c" properties="blue heavy"/>