首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在XPath中使用SelectNodes表达式

在XPath中使用SelectNodes表达式
EN

Stack Overflow用户
提问于 2012-08-10 13:59:00
回答 2查看 1.2K关注 0票数 1

I've seen this question中,Dimitre展示了一种使用XPath 1.0表达式复制ends-with的方法。但是,在SelectNodes调用的上下文中实现它是有困难的。

以前我用过

代码语言:javascript
复制
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表达式给我:

代码语言:javascript
复制
XmlNodeList nodeList = doc.SelectNodes("//x:*[substring(name(.), string-length(name(.)) - string-length('-notification') +1)]", nsmgr);

这很不幸地给了我notification-data-response的根节点。

这是我对XPath的第一次尝试,它看起来就像regex --你要么理解它,要么不理解它。

如何实现表达式,使其只返回以-notification结尾的节点

更新

输入的样本:

代码语言:javascript
复制
<?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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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

输入

代码语言:javascript
复制
 <?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>

输出

代码语言:javascript
复制
<?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‘

本地名称()=给出要在任何点计算的节点的名称,不包括节点名称的前缀字符串长度()长度。

票数 2
EN

Stack Overflow用户

发布于 2012-08-10 14:20:02

迪米特里的解决办法运作得很好。您只需将子字符串‘need’与您要查找的字符串常量进行比较,即:

代码语言:javascript
复制
SelectNodes("//x:*['-notification'=substring(name(.), string-length(name(.)) 
           - string-length('-notification') +1)]")

出于兴趣,如果您可以通过更具体的路径来避免//通配符,那么您将显着地提高大型文档上查询的性能。

编辑

下面是我如何测试这一点(在的xslt解析器(1.0)中):

代码语言:javascript
复制
<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>

返回以“通知”结尾的节点

代码语言:javascript
复制
<root>
    <nodeendsin-notification></nodeendsin-notification>
    <alsonodeendsin-notification></alsonodeendsin-notification>
</root>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11903238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档