在I've seen this question中,Dimitre展示了一种使用XPath 1.0表达式复制ends-with的方法。但是,在SelectNodes调用的上下文中实现它是有困难的。
以前我用过
XmlElement root = doc.DocumentElement;
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("x", root.NamespaceURI);
XmlNodeList nodeList = doc.SelectNodes("//x:*[contains(name(.), '-notification')]", nsmgr);它返回了我想要的所有节点,加上一个我没有返回的节点,其中有一个附加的's‘on the end (has-more-notifications)。
所以我试着用Dimitre表达式给我:
XmlNodeList nodeList = doc.SelectNodes("//x:*[substring(name(.), string-length(name(.)) - string-length('-notification') +1)]", nsmgr);这很不幸地给了我notification-data-response的根节点。
这是我对XPath的第一次尝试,它看起来就像regex --你要么理解它,要么不理解它。
如何实现表达式,使其只返回以-notification结尾的节点
更新
输入的样本:
<?xml version="1.0" encoding="UTF-8"?>
<notification-data-response xmlns="http://checkout.google.com/schema/2" serial-number="16ceae10-a9f1-4ff0-a77b-c3407f2d684a">
<notifications>
<new-order-notification serial-number="653417067275702-00001-7">
</new-order-notification>
<order-state-change-notification serial-number="653417067275702-00005-1">
</order-state-change-notification>
<risk-information-notification serial-number="653417067275702-00005-5">
</risk-information-notification>
<authorization-amount-notification serial-number="653417067275702-00005-6">
</authorization-amount-notification>
</notifications>
<continue-token>CP6u9NeQJxC2y72h-MiUARgG</continue-token>
<has-more-notifications>false</has-more-notifications>
</notification-data-response>发布于 2012-08-10 14:44:05
如果要避免使用命名空间前缀,则必须使用local-name()函数。类似这样的内容应该会给所有以-notification结尾的节点
//node()子字符串(local-name()、string-length(local-name()) -字符串长度( '-notification‘)+ 1、字符串长度(local-name())=’-notification‘
好的..。我在这里测试过这个。你也可以核实..。XPath是一个开放的标准,所以所有的工具都应该能够给出类似的响应。
http://www.xpathtester.com/test
输入
<?xml version="1.0"?>
<notification-data-response xmlns:x="test">
<TPI_ADDRESSES>
<ISPRIMARY>Y</ISPRIMARY>
<data1>
<x:wewe-notification/>
</data1>
<data2>
<x:wewe-notification/>
</data2>
</TPI_ADDRESSES>
</notification-data-response>输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<x:wewe-notification xmlns:x="test"/>
<x:wewe-notification xmlns:x="test"/>
</root>忽略根节点,因为它是为了显示有效的可形成响应而生成的。
现在让我详细分析一下,并向您解释xpath:
"//“就像您不关心目标节点在哪个级别出现一样。 “节点()”--是对任何和每个节点或当前节点的引用.
所以现在:"//node()“
你评价什么?
名称 --您想知道节点的名称中是否包含"-notification“。为此,在LHS中使用子字符串函数。
子字符串(本地名称(),字符串长度(本地名称())-字符串长度(‘-通知’)+ 1,字符串长度(本地名称() RHS是搜索string = '-notification‘
本地名称()=给出要在任何点计算的节点的名称,不包括节点名称的前缀字符串长度()长度。
发布于 2012-08-10 14:20:02
迪米特里的解决办法运作得很好。您只需将子字符串‘need’与您要查找的字符串常量进行比较,即:
SelectNodes("//x:*['-notification'=substring(name(.), string-length(name(.))
- string-length('-notification') +1)]")出于兴趣,如果您可以通过更具体的路径来避免//通配符,那么您将显着地提高大型文档上查询的性能。
编辑
下面是我如何测试这一点(在的xslt解析器(1.0)中):
<root>
<nodeendsin-notification></nodeendsin-notification>
<alsonodeendsin-notification></alsonodeendsin-notification>
<nopethisis-notifications></nopethisis-notifications>
<idontcontainatall></idontcontainatall>
</root>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/root">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="*['-notification'=substring(name(.), string-length(name(.)) - string-length('-notification') +1)]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
</xsl:template>
</xsl:stylesheet>返回以“通知”结尾的节点
<root>
<nodeendsin-notification></nodeendsin-notification>
<alsonodeendsin-notification></alsonodeendsin-notification>
</root>https://stackoverflow.com/questions/11903238
复制相似问题