Получить конкретный узел из XML с XPath - PullRequest
1 голос
/ 12 ноября 2011

У меня есть XML-документ, подобный этому:

<food>
<fruit>
    <apple>
        <product>
            <title>Apple 1</title>
            <price>7</price>
        </product>

        <product>
            <title>Apple 2</title>
            <price>4</price>
        </product>
    </apple>

    <grapes>
        <product>
            <title>Red grapes </title>
            <price>4</price>
        </product>
        <product>
            <title>Green grapes</title>
            <price>6</price>
        </product>
    </grapes>
</fruit>
<drink>
    <water>
        <product>
            <title>Water 1</title>
            <price>1</price>
        </product>
        <product>
            <title>Water 2</title>
            <price>6</price>
        </product>
    </water>
    <soda>
        <product>
            <title>Coca-Cola</title>
            <price>10</price>
        </product>
        <product>
            <title>Sprite</title>
            <price>4</price>
        </product>
    </soda>
</drink>
</food>

У меня есть такая структура XML.

Я хочу выбрать название продукта и цену всех продуктов, стоимость которых превышает 5. Как мне написать выражение XPath, которое делает это?

Ответы [ 2 ]

3 голосов
/ 12 ноября 2011

Полагаю, ваш документ оканчивается на </food>.Это то, что вы хотите ?

//product[price > 5]

РЕДАКТИРОВАТЬ:

Если вы не хотите тег <product>, вы можете сделать это:

//product[price > 5]/*

Однако я считаю, что это последнее решение меньшеудобно, так как мы больше не разграничиваем продукты.

2 голосов
/ 12 ноября 2011

Использовать :

  /*/*/*/product[price > 5]/title 
|
  /*/*/*/product/price[. > 5]

Выбирает объединение:

  1. Все title элементы, у которых есть product родительчье price строковое значение дочернего элемента при обработке как числа больше 5, что является правнуком верхнего элемента XML-документа.

  2. Все price элементы, чья строказначение, если его считать числом больше 5, а его родительский элемент - product, который является правнуком верхнего элемента XML-документа.

Выбранные элементыпредоставляется в наборе узлов (обычно) в порядке документа, что означает, что title и его соответствующие price находятся рядом друг с другом в любой коллекции узлов, созданной соответствующим API-интерфейсом XPath.

В XSLT можно использовать очень простое преобразование, подобное следующему:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="product[price > 5]">
  Name: <xsl:value-of select="title"/>
  <xsl:text>, price </xsl:text>
  <xsl:value-of select="price"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<food>
<fruit>
    <apple>
        <product>
            <title>Apple 1</title>
            <price>7</price>
        </product>

        <product>
            <title>Apple 2</title>
            <price>4</price>
        </product>
    </apple>

    <grapes>
        <product>
            <title>Red grapes </title>
            <price>4</price>
        </product>
        <product>
            <title>Green grapes</title>
            <price>6</price>
        </product>
    </grapes>
</fruit>
<drink>
    <water>
        <product>
            <title>Water 1</title>
            <price>1</price>
        </product>
        <product>
            <title>Water 2</title>
            <price>6</price>
        </product>
    </water>
    <soda>
        <product>
            <title>Coca-Cola</title>
            <price>10</price>
        </product>
        <product>
            <title>Sprite</title>
            <price>4</price>
        </product>
    </soda>
</drink>
</food>

желаемый, правильный результат выдается :

  Name: Apple 1, price 7
  Name: Green grapes, price 6
  Name: Water 2, price 6
  Name: Coca-Cola, price 10

IЕще лучше указать предел цены как глобальный параметр, который передается в преобразование извне.

В этом случае преобразование XSLT 2.0 немного проще:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pLimit" select="5"/>

 <xsl:template match="product[price > $pLimit]">
  Name: <xsl:value-of select="title"/>
  <xsl:text>, price </xsl:text>
  <xsl:value-of select="price"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

Соответствующее преобразование XSLT 1.0 равно :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pLimit" select="5"/>

 <xsl:template match="product">
  <xsl:if test="price > $pLimit">
      Name: <xsl:value-of select="title"/>
      <xsl:text>, price </xsl:text>
      <xsl:value-of select="price"/>
  </xsl:if>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...