编写XPath查询以根据属性和内容匹配元素

时间:2010-02-18 23:19:06

标签: xslt string xpath expression

我有一些像这样的XML:

<topics>
  <topic id="50"/>
  <topic id="51"/>
  <topic id="52"/>
</topics>

<discussions>
  <discussion type="foo">talked about T50 as Discussion 1000</discussion>
  <discussion type="bar">Food is yummy!</discussion>
  <discussion type="foo">talked about T52 as Discussion 1050</discussion>
</discussions>

鉴于特定主题ID($topicID),我想执行以下操作:

  • 设计一个XPath表达式,如果<discussion>的{​​{1}}包含文本type="foo",则该结果为真。

  • 设计一个XPath表达式,假定T$topicID as Discussion <corresponding-discussion-id>,将提取文本$topicID

这可能吗?


更新

对于第一个,我认为我需要类似的东西:

Discussion <corresponding-discussion-id>

2 个答案:

答案 0 :(得分:5)

以下XPath将选择讨论属性type =“foo”并包含文本“T50 as Discussion”(当$ topicid = 50时)。

//discussions/discusson[@type='foo' and contains(., concat('T', $topicid, ' as Discussion ')]

给定一个特定的讨论元素,相应的id由下式给出:

substring-after(normalize-space(.),' as Discussion ')

我们可以通过替换“。”来组合2。在第二个表达式中包含整个第一个表达式。请注意,如果多个讨论与内部表达式匹配,我们将从第二个讨论中连接它们的值。

substring-after(normalize-space(
    //discussions/discusson[@type='foo' and contains(., concat('T', $topicid, ' as Discussion ')]
),' as Discussion ')

如果有多个匹配的讨论,您可以像这样处理它们:

<xsl:for-each select="//topics/topic">
    <xsl:variable name="topicid" select="@id" />
    <xsl:for-each select="//discussions/discusson[@type='foo' and contains(., concat('T', $topicid, ' as Discussion ')]">
        <xsl:variable name="relatedid" select="substring-after(normalize-space(.),' as Discussion ')" />

        <!-- do something with $topicid and $relatedid -->

    </xsl:for-each>
</xsl:for-each>

功能参考:

就个人而言,如果没有Michael Kay的书,我无法想象进行严肃的XSLT开发。

答案 1 :(得分:1)

type=foo的讨论是否包含相应的topicID

/discussions/discussion[@type=foo AND contains(.,'T52')]