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

时间:2011-02-25 16:18:25

标签: xml xpath

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

示例示例:

<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

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

预期输出

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

我不想

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

2 个答案:

答案 0 :(得分:65)

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

  

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

     

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

     

child::node()选择全部   无论如何,上下文节点的子节点   他们的节点类型

所以我猜你的答案是:

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

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

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

答案 1 :(得分:22)

使用此XPath表达式

/*/*/X/node()

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

要验证选择的内容,以下是此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>

,它会产生所需的正确结果:

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

<强>解释

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

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