XPath для получения всех дочерних узлов (элементов, комментариев и текста) без родителя - PullRequest
51 голосов
/ 25 февраля 2011

Мне нужен 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/> 

I DON'ХОЧУ

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

Ответы [ 2 ]

66 голосов
/ 25 февраля 2011

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

child::* выбирает все элементы дочерние элементы контекстного узла

child::text() выделяет весь текстовый узел дочерние элементы узла контекста

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

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

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

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

$doc/PRESENTEDIN/X/descendant::node()
22 голосов
/ 25 февраля 2011

Используйте это выражение 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 Spec, «child::node() выбирает все дочерние элементы узла контекста, независимо от их типа узла».Это означает, что этот элемент теста выбирает любой элемент, текстовый узел, узел комментария и узел инструкции обработки.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...