Как получить текст из нескольких тегов в канале xml, используя одно выражение xpath? - PullRequest
0 голосов
/ 31 декабря 2010

Я пытаюсь разобрать канал XML, который выглядит примерно так:

<item>
<title>item title</title>
<link>item link</link>
<description>item description</description>
</item>

Я пытаюсь найти выражение xpath, которое будет извлекать все детали каждого элемента, чтобы каждый элемент в ленте содержался в своем собственном массиве или каким-либо образом группировался. Я попытался использовать //item/*, но теги не сгруппированы, хотя они правильно упорядочены.

Есть ли способ сделать это?

редактирование:

[
[title1, link1, desc1],
[title2, link2, desc2],
[title3, link3, desc3]
]

Ответы [ 4 ]

0 голосов
/ 01 января 2011

Вы не указали язык, но если вы используете Python (именно так выглядит структура представленных вами данных), это достаточно просто сделать с помощью lxml:

 >>> from lxml import etree
 >>> d = etree.fromstring("""<doc>
 <item>
  <title>item 1 title</title>
  <link>item 1 link</link>
  <description>item 1 description</description>
 </item>
 <item>
  <title>item 2 title</title>
  <link>item 2 link</link>
  <description>item 2 description</description>
 </item>
</doc>""")
>>> [[e.xpath("title")[0].text,
      e.xpath("description")[0].text,
      e.xpath("link")[0].text]
     for e in d.xpath("/doc/item")]
[['item 1 title', 'item 1 description', 'item 1 link'], ['item 2 title', 'item 2 description', 'item 2 link']]

Это не так просто сделать в понимании списка, если структура XML ненадежна; вышеприведенное прерывается, если, например, элемент item не имеет дочернего элемента 'link'.

0 голосов
/ 31 декабря 2010

С http://www.w3.org/TR/xpath/#section-Introduction

Выражение вычисляется для получения объекта, который имеет один из следующих четырех основных типов:

  • набор узлов (неупорядоченныйнабор узлов без дубликатов)
  • логическое (истина или ложь)
  • число (число с плавающей точкой)
  • строка (последовательность символов UCS)

Итак, нет типа данных структуры, подобного кортежам.«Стандартное» решение для вашей задачи - выбрать родителей и перебрать их, получив детей любым методом DOM API.

0 голосов
/ 31 декабря 2010

Вот выражение XPath 2.0 , возвращающее последовательность (при условии, что входной документ XML из ответа Стефаноса):

for $item in /root/item
  return ($item/title/text(), $item/link/text(), $item/description/text())

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

0 голосов
/ 31 декабря 2010

С этим входом

<root>
<item>
    <title>item title</title>
    <link>item link</link>
    <description>item description</description>
</item>
<item>
    <title>item2</title>
    <link>link2</link>
    <description>description2</description>
</item>
</root>

а это xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="//item">
        <xsl:value-of select="./title"/><xsl:text>
</xsl:text>
        <xsl:value-of select="./link"/><xsl:text>
</xsl:text>
        <xsl:value-of select="./description"/><xsl:text>
</xsl:text>
    </xsl:template>

</xsl:stylesheet>

Вы получите этот вывод

item title
item link
item description

item2
link2
description2

Надеюсь, это помогло ..

...