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 & 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>
Ответы
Ответ 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::
является первичной осью и используется, когда ни одна ось не указана явно).