Подтвердить что ты не робот

XPath для получения всех дочерних узлов (элементов, комментариев и текста) без родительских

Мне нужен XPath для извлечения всех дочерних узлов (включая текстовый элемент, элемент комментария и дочерние элементы) без родительского элемента. Любая помощь

Пример примера:

<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>
4b9b3361

Ответ 1

Из документации XPath (http://www.w3.org/TR/xpath/#location-paths):

child::* выбирает весь элемент дети контекста node

child::text() выбирает весь текст nodeдети контекста node

child::node() выбирает все дети контекста node, что угодно их тип node

Итак, я думаю, ваш ответ:

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

И если вы хотите сгладить массив всех вложенных узлов:

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

Ответ 2

Используйте это выражение XPath:

/*/*/X/node()

Здесь выбирается любой node (элемент, текст 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 />

Объяснение

  • Как определено в W3 XPath 1.0 Spec, "child::node() выбирает всех детей из контекст node, независимо от их типа node". Это означает, что этот элемент node -test выбирает любой элемент, text- node, comment- node и обработчик-инструкция node.

  • node() является аббревиатурой child::node() (потому что child:: является первичной осью и используется, когда ни одна ось не указана явно).