XML:
<amenities>
<record>
<thekey>77</thekey>
<thevalue>Balcony</thevalue>
</record>
<record>
<thekey>75</thekey>
<thevalue>Cable</thevalue>
</record>
<record>
<thekey>35</thekey>
<thevalue>High Speed Internet</thevalue>
</record>
<record>
<thekey>16</thekey>
<thevalue>Fireplace</thevalue>
</record>
<record>
<thekey>31</thekey>
<thevalue>Garage</thevalue>
</record>
<record>
<thekey>32</thekey>
<thevalue>Phone</thevalue>
</record>
</amenities>
我需要检查设施中的每条记录,以确定是否存在“35”(高速互联网)。设施中的记录可能有所不同。有时它会有35(高速互联网),有时它不会。我需要能够在XSLT中检查这一点。
答案 0 :(得分:1)
在XSLT中有不同的写入条件的方法,听起来好像你只想编写一个与你的条件匹配的模式而另一个不匹配它:
<xsl:template match="amenities[record[thekey = 35 and thevalue = 'High Speed Internet']]">high speed internet exists</xsl:template>
<xsl:template match="amenities[not(record[thekey = 35 and thevalue = 'High Speed Internet'])]">high speed internet does not exist</xsl:template>
当然,您也可以编写与amenities
元素匹配的模板,然后在内部使用xsl:if
或xsl:choose
。
<xsl:template match="amenities">
<xsl:choose>
<xsl:when test="record[thekey = 35 and thevalue = 'High Speed Internet']">exists</xsl:when>
<xsl:otherwise>does not exist</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 1 :(得分:0)
在最简单的形式中,此问题的解决方案是单个纯XPath表达式:
/*/record[thekey = 35 and thevalue = 'High Speed Internet']
这将选择所有record
元素,这些元素是XML文档顶部元素的子元素,并且具有带有字符串值的thekey
子元素,当转换为数字时,该元素等于35且具有一个thevalue
子节点,其字符串值为字符串'High Speed Internet'。
不的所有record
元素都具有此属性:
/*/record[not(thekey = 35 and thevalue = 'High Speed Internet')]
您可以通过简单地将相应的XPath表达式指定为select
(推荐)或xsl:apply-templates
指令的xsl:for-each
参数来处理这些节点。
<xsl:apply-templates select="/*/record[thekey = 35 and thevalue = 'High Speed Internet']"/>
请注意,仅使用从此XPath表达式派生的匹配模式指定xsl:template
,并不能完全保证将选择执行模板 - 这取决于是否应用了模板(显式或隐式)。
访问所有感兴趣节点的高效,仅限XSLT的方法是使用密钥:
<xsl:key name="kRecByKeyAndVal" match="record" use="concat(thekey,'+',thevalue)"/>
上面根据record
和thekey
子项的串联(通过合适的分隔符字符串('+')消除歧义,指定所有thevalue
元素的索引,其中保证不会出现在这些值中。)
然后,引用所有record
元素,其中thekey
子元素字符串值为“35”,而thevalue
子元素字符串值为“高速互联网” '是:
key('kRecByKeyAndVal', '35+High Speed Internet')
只要表达式不止一次被使用,使用键可以提高效率(速度)。