Xpath查询以根据条件选择忽略后代的所有元素 [英] Xpath query to select all elements ignoring descendants based on criteria

查看:35
本文介绍了Xpath查询以根据条件选择忽略后代的所有元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试选择所有 erase</set> 元素,以便如果两个或多个元素具有 erase</set>code> 在层次结构中(例如: 都有 erase)然后只需要选择父节点名称中的元素(即 在这种情况下).

I am trying to select all the <set>erase</set> elements such that if two or more elements have the <set>erase</set> in hierarchy (Ex: <b> and <d> both have <set>erase</set>) then only the element in parent node name has to be selected(ie <b> in this case).

下面的示例xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a>
    <b>
        <set>erase</set>
        <d>
            <set>erase</set>
        </d>
    </b>

    <c>
        <x></x>
    </c>

    <e>
        <y>
            <set>erase</set>
            <q></q>
        </y>
        <z>
            <p>
                <set>erase</set>
            </p>
        </z>
    </e>
</a>

当我使用 query =//set[contains(.,'erase')] 我得到所有 <set>erase</set> 的节点列表b,d,y,p 在结果集中.

When I use the query = //set[contains(.,'erase')] I get all <set>erase</set> of nodesList b,d,y,p in result set.

我需要帮助构建查询以选择 <set>erase</set>byp.

I need help in framing the query to select <set>erase</set> of b , y and p.

推荐答案

这里是相同的解决方案:

Here is the same solution:

一个准确选择所需元素的 XPath 表达式是:

          //*[set[. = 'erase' and not(node()[2])]
             and
              not(ancestor::*
                     [set
                        [. = 'erase' and not(node()[2])]
                     ]
                  )
              ]

基于 XSLT 的验证:

<xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:output omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>

         <xsl:template match="/">
             <xsl:for-each select=
             "//*[set[. = 'erase' and not(node()[2])]
                 and
                  not(ancestor::*
                         [set
                            [. = 'erase' and not(node()[2])]
                         ]
                      )
                  ]">

              <xsl:value-of select="name()"/>
              <xsl:text>&#xA;</xsl:text>
            </xsl:for-each>
         </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<a>
    <b>
        <set>erase</set>
        <d>
            <set>erase</set>
        </d>
    </b>
    <c>
        <x></x>
    </c>
    <e>
        <y>
            <set>erase</set>
            <q></q>
        </y>
        <z>
            <p>
                <set>erase</set>
            </p>
        </z>
    </e>
</a>

计算包含的 XPath 表达式并输出所选元素的名称 - 正确且符合预期:

b
y
p

如果您需要选择上述所选元素的 set 子元素,只需在上面的 XPath 表达式中附加 /set:

If you need to select the set children of the selected above elements, just append the above XPath expression with /set:

          //*[set[. = 'erase' and not(node()[2])]
             and
              not(ancestor::*
                     [set
                        [. = 'erase' and not(node()[2])]
                     ]
                  )
              ]
               /set

同样,基于 XSLT 的验证:

<xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:output omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>

         <xsl:template match="/">
             <xsl:copy-of select=
             "//*[set[. = 'erase' and not(node()[2])]
                 and
                  not(ancestor::*
                         [set
                            [. = 'erase' and not(node()[2])]
                         ]
                      )
                  ]
                   /set
                  "/>
         </xsl:template>
</xsl:stylesheet>

这个转换只是计算上面的 XPath 表达式并将正确选择的三个 set 元素复制到输出中:

This transformation just evaluates the above XPath expression and copies to the output the correctly selected three set elements:

<set>erase</set>
<set>erase</set>
<set>erase</set>

这篇关于Xpath查询以根据条件选择忽略后代的所有元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆