我有以下XML:
<A>
<B>
<C Since="2011-09-26T11:12:41.1383089Z">
<E Name="One" AnotherDate="2011-09-26T10:54:05.7025781Z"/>
<E Name="Two" AnotherDate="2011-09-26T11:54:05.7025781Z"/>
</C>
</B>
</A>
我的Xpath表达式如下所示:
//A/B/C/E[@AnotherDate <= ../@Since]
这适用于XMLSpy,也适用于T-SQL 2008查询
where X.exists(xpathexpression)=1
但不是在带有XmlDocument.SelectNodes()的.NET 3.5中。
据我所知,xpath文档可以在XPATH 1.0中支持该查询,.NET支持该版本。
我想要实现的目标: 我想选择 E 的所有元素 E 早于或等于其父元素 C 的,属性。
所以:我做错了什么,或者我可以改变什么来实现类似的东西。 请注意,查询也应该在给定的sql where子句中起作用。
答案 0 :(得分:1)
这非常简单。使用强>:
/A/B/C/E
[not(translate(@AnotherDate, '-:TZ', '')
>
translate(../@Since, '-:TZ', '')
)
]
基于XSLT的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"/A/B/C/E
[not(translate(@AnotherDate, '-:TZ', '')
>
translate(../@Since, '-:TZ', '')
)
]
"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<A>
<B>
<C Since="2011-09-26T11:12:41.1383089Z">
<E Name="One" AnotherDate="2011-09-26T10:54:05.7025781Z"/>
<E Name="Two" AnotherDate="2011-09-26T11:54:05.7025781Z"/>
</C>
</B>
</A>
将所需的正确结果(仅选定的一个节点)复制到输出:
<E Name="One" AnotherDate="2011-09-26T10:54:05.7025781Z" />
解释:使用标准XPath 1.0函数 translate()
从日期时间值中删除所有非数字字符,以便剩下的全部然后可以将数字字符串正确地作为数字进行比较。
答案 1 :(得分:0)
在我看来,这符合the specification的行为:
当要比较的对象都不是节点集并且运算符是&lt; =,&lt;,&gt; =或&gt;时,则通过将两个对象转换为数字并根据IEEE比较数字来比较对象。 754.
将字符串转换为数字:
一个字符串,由可选的空格后跟一个可选的减号,后跟一个数字后跟空格,转换为最接近的IEEE 754数字(根据IEEE 754舍入到最接近的规则)到数学值由字符串表示;任何其他字符串都转换为NaN
因此,在您的情况下,比较两个NaN,返回false。因此,不返回任何节点。在XPath 2.0中,行为有所不同,这可能是它在其他环境中工作的原因。
我认为你不能只使用XPath 1.0选择这样的节点。所以,我认为你不能仅仅通过使用单如果你想使用单个XPath 1.0查询实现这一点,你必须克服它的局限性。请参阅Dimitre的答案如何做到这一点。SelectNodes()
来实现。