xml XPath 获取没有父节点的所有子节点(元素、注释和文本)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5119655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 14:34:22  来源:igfitidea点击:

XPath to get all child nodes (elements, comments, and text) without parent

xmlxpath

提问by kadalamittai

I need an XPath to fetch all ChildNodes ( including Text Element, Comment Element & Child Elements ) without Parent Element. Any help

我需要一个 XPath 来获取所有没有父元素的子节点(包括文本元素、注释元素和子元素)。任何帮助

Sample Example:

示例示例:

<DOC>
<PRESENTEDIN>
    <X>
        First Text Node #1 
        <y> Y can Have Child Nodes # 
            <child> deep to it </child> 
         </y>
         Second Text Node #2 <z/> 
    </X>
    <EVTS>
        <evt/>
        <evt>
            <mtg_descr> SAE 2006 World Congress &amp; Exhibition </mtg_descr>
            <sess_descr> Advanced Hybrid Vehicle Powertrains (Part 1 of 5) </sess_descr>
            <loc> Detroit,MI,United States </loc>
            <sess_prod_grp_cd> TSESS </sess_prod_grp_cd>
            <sess_evt_name> P13 </sess_evt_name>
            <sess_gen_num> 138352 </sess_gen_num>
            <mtg_start_dt> 04/03/2006 </mtg_start_dt>
            <mtg_end_dt> 04/06/2006 </mtg_end_dt>
            <desig> CONGRESS-2006 </desig>
        </evt>
    </EVTS>
    <EVTTYPE>PAPER</EVTTYPE>
    <SUPERTECH>
        <![CDATA[C8585]]>
    </SUPERTECH>
</PRESENTEDIN>

XPATH TRIED

XPATH 尝试

   1. $doc/PRESENTEDIN/X
   2. $doc/PRESENTEDIN/X/descendant::*
   2. $doc/PRESENTEDIN/X/self::*

EXPECTED OUTPUT

预期产出

    First Text Node #1 
    <y> Y can Have Child Nodes # 
        <child> deep to it </child> 
     </y>
     Second Text Node #2 <z/> 

I DON'T WANT

我不想

<X>
  First Text Node #1 
        <y> Y can Have Child Nodes # 
            <child> deep to it </child> 
         </y>
         Second Text Node #2 <z/> 
</X>

回答by linepogl

From the documentation of XPath ( http://www.w3.org/TR/xpath/#location-paths):

从 XPath ( http://www.w3.org/TR/xpath/#location-paths)的文档中:

child::*selects all element children of the context node

child::text()selects all text node children of the context node

child::node()selects all the children of the context node, whatever their node type

child::*选择上下文节点的所有元素子节点

child::text()选择上下文节点的所有文本节点子节点

child::node()选择上下文节点的所有子节点,无论它们的节点类型如何

So I guess your answer is:

所以我猜你的答案是:

$doc/PRESENTEDIN/X/child::node()

And if you want a flatten array of all nested nodes:

如果你想要一个所有嵌套节点的扁平数组:

$doc/PRESENTEDIN/X/descendant::node()

回答by Dimitre Novatchev

Use this XPath expression:

使用这个 XPath 表达式

/*/*/X/node()

This selects any node (element, text node, comment or processing instruction) that is a child of any Xelement that is a grand-child of the top element of the XML document.

这将选择作为任何元素的子元素的任何节点(元素、文本节点、注释或处理指令),X该元素是 XML 文档顶部元素的孙子元素。

To verify what is selected, here is this XSLT transformation that outputs exactly the selected nodes:

为了验证选择了什么,这里是这个 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="/*/*/X/node()"/>
 </xsl:template>
</xsl:stylesheet>

and it produces exactly the wanted, correct result:

它产生的正是想要的、正确的结果:

   First Text Node #1            
    <y> Y can Have Child Nodes #                
        <child> deep to it </child>
    </y>            Second Text Node #2 
    <z />

Explanation:

说明

  1. As defined in the W3 XPath 1.0Spec, "child::node()selects all the children of the context node, whatever their node type." This means that any element, text-node, comment-node and processing-instruction node children are selected by this node-test.

  2. node()is an abbreviation of child::node()(because child::is the primary axis and is used when no axis is explicitly specified).

  1. 正如W3 XPath 1.0规范中定义的那样,“child::node()选择上下文节点的所有子节点,无论它们的节点类型如何。” 这意味着此节点测试选择任何元素、文本节点、注释节点和处理指令节点子节点。

  2. node()child::node()(因为child::是主轴,在没有明确指定轴时使用)的缩写。