我有两个节点集的字符串令牌.一组包含以下值:
/Geography/North America/California/San Francisco /Geography/Asia/Japan/Tokyo/Shinjuku
另一组包含以下值:
/Geography/North America/ /Geography/Asia/Japan/
我的目标是找到两者之间的“匹配”.当集合1中的任何字符串以集合2中的字符串开头时进行匹配.例如,匹配将在/ Geography / North America / California / San Francisco和/ Geography / North America /之间进行,因为来自集合1的字符串以第2集中的字符串开头.
我可以使用第三方扩展来使用通配符来比较字符串.我也可以在Xpath中使用正则表达式.
我的问题是如何构建Xpath以在两个集合的所有节点之间使用函数进行选择? XSL也是一个可行的选择.
这个XPATH:
count($set1[.=$set2])
会产生set1和set2之间的交集计数,但它是1比1的比较.是否可以使用其他一些比较节点的方法?
编辑:我确实让这个工作,但我通过使用一些其他第三方扩展作弊获得相同的结果.我仍然对其他方法感兴趣.
<xsl:variable name="matches" select="$set1[starts-with(.,$set2)]"/>
将$matches设置为包含$set1中每个节点的节点集,该节点的文本值以$set2中节点的文本值开头.这就是你要找的,对吧?
编辑:
好吧,我对此错了.这就是原因.
starts-with期望它的两个参数都是字符串.如果它们不是,它会在评估函数之前将它们转换为字符串.
如果给它一个节点集作为其参数之一,它将使用节点集的字符串值,该值是集合中第一个节点的文本值.所以在上面,$set2永远不会被搜索;只检查列表中的第一个节点,因此谓词只会在$set1中找到以$set2中第一个节点的值开头的节点.
我被误导了,因为这种模式(我在过去几天里一直使用很多)确实有效:
<xsl:variable name="hits" select="$set1[. = $set2]"/>
但该谓词使用的是节点集之间的比较,而不是文本值之间的比较.
执行此操作的理想方法是嵌套谓词.也就是说,“我想找到$set1中的每个节点,其中$set2中有一个节点,其值以……开头”,这就是XPath发生故障的地方.从什么开始?你想写的是:
<xsl:variable name="matches" select="$set1[$set2[starts-with(?,.)]]"/>
只有没有你可以写的表达?这将返回外部谓词当前正在测试的节点. (除非我遗漏了一些令人目眩的明显事物.)
要获得所需的内容,您必须单独测试每个节点:
<xsl:variable name="matches"> <xsl:for-each select="$set1"> <xsl:if test="$set2[starts-with(current(),.)]"> <xsl:copy-of select="."/> </xsl:if> </xsl:for-each> </xsl:variable>
这不是一个非常令人满意的解决方案,因为它评估结果树片段,而不是节点集.如果要在XPath表达式中使用该变量,则必须使用扩展函数(如msxsl:node-set)将RTF转换为节点集.