XPath包含(text(),';一些字符串';)不';当与包含多个文本子节点的节点一起使用时,无法工作

XPath包含(text(),';一些字符串';)不';当与包含多个文本子节点的节点一起使用时,无法工作,xpath,dom4j,Xpath,Dom4j,我对dom4j的Xpath包含有一个小问题 假设我的XML是 <Home> <Addr> <Street>ABC</Street> <Number>5</Number> <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment> </Addr> </Home&g

我对dom4j的Xpath包含有一个小问题

假设我的XML是

<Home>
    <Addr>
        <Street>ABC</Street>
        <Number>5</Number>
        <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
    </Addr>
</Home>
我假设查询仍然应该返回元素,因为它应该找到元素并在其上运行contains,但它没有

下面的查询返回元素,但它返回的远不止元素,它还返回父元素。。。这对问题来说是不可取的

//*[contains(text(),'ABC')]
有人知道只返回元素
的xpath查询吗?

标记包含两个文本节点和两个作为子节点的

节点

您的xpath表达式是

//*[contains(text(),'ABC')]
为了打破这一局面

  • *
    是一个与任何元素(即标记)匹配的选择器--它返回一个节点集
  • []
    是在该节点集中的每个单独节点上操作的条件。如果其操作的任何单个节点与括号内的条件匹配,则匹配
  • text()
    是一个选择器,它匹配作为上下文节点子节点的所有文本节点——它返回一个节点集
  • contains
    是一个对字符串进行操作的函数。如果传递给它一个节点集,则该节点集为。因此,它只能匹配
    元素中的第一个文本节点,即
    等等等等。因为这不匹配,所以结果中不会出现
  • 您需要将此更改为

    //*[text()[contains(.,'ABC')]]
    
  • *
    是一个与任何元素(即标记)匹配的选择器--它返回一个节点集
  • 外部
    []
    是一个条件,它在该节点集中的每个单独节点上运行——这里它在文档中的每个元素上运行
  • text()
    是一个选择器,它匹配作为上下文节点子节点的所有文本节点——它返回一个节点集
  • 内部的
    []
    是一个条件,它在该节点集中的每个节点上运行——这里是每个单独的文本节点。每个单独的文本节点都是括号内任何路径的起点,也可以在括号内显式地称为
    。如果其操作的任何单个节点与括号内的条件匹配,则匹配
  • contains
    是一个对字符串进行操作的函数。在这里,它被传递给一个单独的文本节点(
    )。由于它被分别传递给
    标记中的第二个文本节点,因此它将看到
    'ABC'
    字符串并能够匹配它

  • [包含(text(),“”)]
    仅返回true或false。它不会返回任何元素结果。

    我花了一点时间,但最终找到了答案。包含下面一些文本的自定义xpath非常适合我

    //a[contains(text(),'JB-')]
    
    XML文档:

    <Home>
        <Addr>
            <Street>ABC</Street>
            <Number>5</Number>
            <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
        </Addr>
    </Home>
    
    /*
    匹配任何一个。即,除了根节点之外的任何元素

    […]
    是一个,它过滤节点集。它返回
    ..
    true
    的节点:

    谓词过滤节点集[…]以生成新的节点集。对于要筛选的节点集中的每个节点,谓词expr的计算结果为[…];如果该节点的PredicateExpr计算结果为true,则该节点将包含在新节点集中;否则,不包括在内

    contains('haystack','needle')
    返回
    true
    if
    haystack
    needle

    函数:布尔包含(字符串,字符串)

    如果第一个参数字符串包含第二个参数字符串,则contains函数返回true,否则返回false

    但是
    contains()
    将字符串作为其第一个参数。它是通过节点传递的。要处理作为第一个参数传递的每个节点或节点集都是通过
    string()
    函数传递给字符串的问题,请执行以下操作:

    通过调用string函数,参数被转换为string类型

    string()

    通过返回文档顺序中第一个节点集中节点的字符串值,将节点集转换为字符串。如果节点集为空,则返回空字符串

    字符串的

    元素节点的字符串值是元素节点的所有文本节点子体的字符串值按文档顺序的串联

    字符串值

    文本节点的字符串值是字符数据

    因此,基本上
    字符串值
    是包含在节点中的所有文本(所有后代文本节点的串联)

    是匹配任何文本节点的节点测试:

    节点test text()对于任何文本节点都为true。例如,child::text()将选择上下文节点的文本节点子节点

    话虽如此,
    /*[contains(text(),'ABC')]
    匹配任何元素(但根节点除外),其第一个文本节点包含
    ABC
    。因为
    text()。但是
    contains()
    只接受第一个。因此,对于上面的文档,路径与
    Street
    元素匹配

    下面的表达式
    /*[text()[contains(,'ABC')]
    匹配任何元素(但根节点除外),该元素至少有一个子文本节点,包含
    ABC
    <代码>
    表示上下文节点。在本例中,它是除根节点外的任何元素的子文本节点。因此,对于上面的文档,路径与
    Street
    Comment
    元素匹配

    现在,
    /*[contains(,'ABC')]
    匹配包含
    ABC
    的任何元素(但根节点除外)(在后代文本节点的串联中)。对于上面的文档,它与
    主页
    匹配,
    
    
    <Home>
        <Addr>
            <Street>ABC</Street>
            <Number>5</Number>
            <Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
        </Addr>
    </Home>
    
    //*[contains(text(), 'ABC')]
    
    //*[text()[contains(.,'ABC')]]/text()[contains(.,"ABC")]
    
    //*[text()='ABC'] 
    
    <street>ABC</street>
    <comment>BLAH BLAH BLAH <br><br>ABC</comment>