我有以下XML文件:
<document>
<article>
<head>headline 1</head>
<text>
<paragraph>foo</paragraph>
<paragraph>bar</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>some text</source>
<portal>ABC</portal>
<ID number="1"/>
</article>
<article>
<head>headline 2</head>
<text>
<paragraph>lorem ipsum</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>another source</source>
<portal>DEF</portal>
<ID number="2"/>
</article>
</document>
现在我想返回头节点之后出现的每篇文章的所有节点 在门户节点之前。因此,我正在研究XPath 2节点比较(&lt;&lt;&gt;&gt;运算符)。
到目前为止我所拥有的是以下内容,它返回空:
<xsl:template match="/">
<xsl:copy-of select="/document/article/head/following-sibling::*[. << ./article/portal]"/>
</xsl:template>
如何修复xpath查询?
答案 0 :(得分:2)
一个简单的XPath 1.0表达式适用于这种情况:
/document/article/head/following-sibling::*[following-sibling::portal]
答案 1 :(得分:2)
使用强>:
/*/*/node()[. >> ../head and ../portal >> .]
这是一个完整的转型:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select="/*/*/node()[. >> ../head and ../portal >> .]"/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<document>
<article>
<head>headline 1</head>
<text>
<paragraph>foo</paragraph>
<paragraph>bar</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>some text</source>
<portal>ABC</portal>
<ID number="1"/>
</article>
<article>
<head>headline 2</head>
<text>
<paragraph>lorem ipsum</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>another source</source>
<portal>DEF</portal>
<ID number="2"/>
</article>
</document>
产生了想要的正确结果:
<text>
<paragraph>foo</paragraph>
<paragraph>bar</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>some text</source>
<text>
<paragraph>lorem ipsum</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>another source</source>
<强>更新强>:
在评论中,Roman Pekar指定了一项新要求:他希望获得每篇文章的第一个 head
和portal
之间的所有此类节点。
当然,这很简单 - 只需将上述表达更改为:
/*/*/node()[. >> ../head[1] and ../portal[1] >> .]
答案 2 :(得分:2)
我经常在SQL Server中使用xml,所以当我看到Dimitre Novatchev回答时,我已经在SSMS中尝试过了。它没有用,因为SQL服务器中的XQuery实现是a statically typed language and does static type checking,所以我试图找到这个表达式的SQL Server形式。这是:
/document/article/*[. >> ../head[1] and . << ../portal[1]]
完整查询将是
declare @Data xml
select @Data = '
<document>
<article>
<head>headline 1</head>
<text>
<paragraph>foo</paragraph>
<paragraph>bar</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>some text</source>
<portal>ABC</portal>
<ID number="1"/>
</article>
<article>
<head>headline 2</head>
<text>
<paragraph>lorem ipsum</paragraph>
</text>
<date>
<day>10</day>
<month>05</month>
<year>2002</year>
</date>
<source>another source</source>
<portal>DEF</portal>
<ID number="2"/>
</article>
</document>
'
select @Data.query('/document/article/*[. >> ../head[1] and . << ../portal[1]]')
答案 3 :(得分:1)
我认为您有一个很好的建议,根本不使用<<
,但如果您想使用它,我认为<xsl:copy-of select="/document/article/head/following-sibling::*[. << parent::article/portal]"/>
会修复您的尝试。