使用XPath从XML获取特定节点

使用XPath从XML获取特定节点,xml,xslt,xpath,nodes,Xml,Xslt,Xpath,Nodes,我有这样一个XML文档: <food> <fruit> <apple> <product> <title>Apple 1</title> <price>7</price> </product> <product> <title>Apple

我有这样一个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>

苹果1
7.
苹果2
4.
红葡萄
4.
绿葡萄
6.
水1
1.
水2
6.
可口可乐
10
(传说中的)精灵
4.
我有一个这样的XML结构


我想了解所有价格在5美元以上的产品的名称和价格。如何编写一个XPath表达式来实现这一点?

我假设您的文档以
结尾。这就是你想要的吗

//product[price > 5]
编辑:

如果不需要
标记,可以执行以下操作:

//product[price > 5]/*

但是,我发现最后一个解决方案不太方便,因为我们不再对产品进行定界。

我想您的文档以
结尾。这就是你想要的吗

//product[price > 5]
编辑:

如果不需要
标记,可以执行以下操作:

//product[price > 5]/*
但是,我发现最后一个解决方案不太方便,因为我们不再对产品进行界定。

使用

  /*/*/*/product[price > 5]/title 
|
  /*/*/*/product/price[. > 5]
<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
<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>
这将选择以下项的并集:

  • 所有
    title
    元素都有
    product
    父元素,其
    price
    子元素的字符串值在作为数字处理时大于5,这是XML文档顶部元素的曾孙

  • 所有
    price
    元素,当作为数字处理时,其字符串值大于5,并且其父元素是XML文档顶部元素的曾孙
    产品

  • 所选元素(通常)按文档顺序在节点集中提供,这意味着在由相应XPathAPI生成的任何节点集合中,
    标题
    及其相应的
    价格
    彼此相邻

    在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>
    
    最好将价格限制指定为全局参数,从外部传递给转换。

    在本例中,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转换是

      /*/*/*/product[price > 5]/title 
    |
      /*/*/*/product/price[. > 5]
    
    <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
    
    <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>
    
    
    姓名:
    价格
    
    使用

      /*/*/*/product[price > 5]/title 
    |
      /*/*/*/product/price[. > 5]
    
    <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
    
    <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>
    
    这将选择以下项的并集:

  • 所有
    title
    元素都有
    product
    父元素,其
    price
    子元素的字符串值在作为数字处理时大于5,这是XML文档顶部元素的曾孙

  • 所有
    price
    元素,当作为数字处理时,其字符串值大于5,并且其父元素是XML文档顶部元素的曾孙
    产品

  • 所选元素(通常)按文档顺序在节点集中提供,这意味着在由相应XPathAPI生成的任何节点集合中,
    标题
    及其相应的
    价格
    彼此相邻

    在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>
    
    最好将价格限制指定为全局参数,从外部传递给转换。

    在本例中,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转换是

      /*/*/*/product[price > 5]/title 
    |
      /*/*/*/product/price[. > 5]
    
    <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
    
    <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>
    
    
    姓名:
    价格
    
    错过了。当然,它可能位于XML结构中。当然,在XML结构中,您的示例起作用,它给了我一个结果。但是如果我想展示一切,我该怎么做?我需要使用for-Each循环还是不使用循环就可以完成?嗯,我对XSLT不友好(我使用xquery)。我想您需要使用for each循环(比如这里:)。这个答案中的XPath表达式给出了所有结果,而不仅仅是一个结果。但是,在XPath之外访问结果的方式要么提取单个字符串值,要么提取节点集,等等。您最初的问题只询问了XPath,但现在您需要告诉我们您使用XPath的环境(是否在XSLT中?@LarsH我认为它是XSLT,因为这个问题的标签提到了它:)@fflorent:一个合理的假设。但有时人们在他们的问题上贴上标签,却不理解或没有太多意义。。。因此,很难知道xslt标记是指“我正在使用xslt”还是“我认为xslt可能是答案的一部分”或“我认为xslt与XPath有关”。您的示例很有效,它给出了一个结果。但是如果我想展示一切,我该怎么做?我需要使用for-Each循环还是不使用循环就可以完成?嗯,我对XSLT不友好(我使用xquery)。我想您需要使用for each循环(比如这里:)。这个答案中的XPath表达式给出了所有结果,而不仅仅是一个结果。但是,在XPath之外访问结果的方式要么提取单个字符串值,要么提取节点集,等等。您最初的问题只询问了XPath,但现在您需要告诉我们您使用XPath的环境(是否在XSLT中?@LarsH我认为它是XSLT,因为这个问题的标签提到了它:)@fflorent:一个合理的假设。但有时人们在他们的问题上贴上标签,却不理解或没有太多意义。。。因此很难知道xslt标记是指“我正在使用xslt”还是“我认为xslt可能是答案的一部分”或“我认为xslt与XPath有关”。