Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xpath 属性和元素上的xquery筛选器_Xpath_Xquery - Fatal编程技术网

Xpath 属性和元素上的xquery筛选器

Xpath 属性和元素上的xquery筛选器,xpath,xquery,Xpath,Xquery,我有以下简单的XML文档: <?xml version="1.0" encoding="UTF-8"?> <cars> <car> <data attrib="Make"> <text>Volvo</text> </data> <data attrib="Model"> <text>85

我有以下简单的XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<cars>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>855</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>745</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>V70R</text>
        </data>
    </car>
</cars>
这将返回以下结果:

<data attrib="Model"><text>855</text></data>
855
我希望XPath返回匹配的整个

因此,返回数据如下所示:

<cars>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>855</text>
        </data>
    </car>
</cars>

沃尔沃汽车
855

我如何修改上面的XPath表达式来实现这一点?

XPath返回您所访问的任何节点-在您的示例中,您将返回到
数据,因此这就是您要返回的内容。如果您想要
car
,请将谓词放在
car
之后

/cars/car[data/@attrib='Model' and data/text='855']
或者,稍微短一点

/cars/car[data[@attrib='Model' and text='855']]
你可以随时运行它

XQuery生成所需的输出:

<cars>
  {/cars/car[data[@attrib='Model' and text='855']]}
</cars>

{/cars/car[data[@attrib='Model'和text='855']]

这里有一个完整的、可能是最短的XSLT解决方案之一:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" />

 <xsl:template match="/*">
     <cars>
       <xsl:copy-of select="car[data[@attrib='Model' and text='855']]"/>
   </cars>
 </xsl:template>
</xsl:stylesheet>
<cars>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>855</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>745</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>V70R</text>
        </data>
    </car>
</cars>
<cars>
   <car>
      <data attrib="Make">
         <text>Volvo</text>
      </data>
      <data attrib="Model">
         <text>855</text>
      </data>
   </car>
</cars>

但是,使用众所周知的进行以下转换既易于编写,又提供了最大的灵活性、可扩展性和可维护性:

   <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>

     <xsl:template match="car[not(data[@attrib='Model' and text='855'])]"/>
    </xsl:stylesheet>

当对提供的XML文档应用这两种转换之一时:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" />

 <xsl:template match="/*">
     <cars>
       <xsl:copy-of select="car[data[@attrib='Model' and text='855']]"/>
   </cars>
 </xsl:template>
</xsl:stylesheet>
<cars>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>855</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>745</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>V70R</text>
        </data>
    </car>
</cars>
<cars>
   <car>
      <data attrib="Make">
         <text>Volvo</text>
      </data>
      <data attrib="Model">
         <text>855</text>
      </data>
   </car>
</cars>

沃尔沃汽车
855
沃尔沃汽车
745
沃尔沃汽车
V70R
生成所需的正确结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" />

 <xsl:template match="/*">
     <cars>
       <xsl:copy-of select="car[data[@attrib='Model' and text='855']]"/>
   </cars>
 </xsl:template>
</xsl:stylesheet>
<cars>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>855</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>745</text>
        </data>
    </car>
    <car>
        <data attrib="Make">
            <text>Volvo</text>
        </data>
        <data attrib="Model">
            <text>V70R</text>
        </data>
    </car>
</cars>
<cars>
   <car>
      <data attrib="Make">
         <text>Volvo</text>
      </data>
      <data attrib="Model">
         <text>855</text>
      </data>
   </car>
</cars>

沃尔沃汽车
855
说明

  • 第一个转换生成顶部元素
    cars
    ,然后简单地选择想要的
    car
    元素并将其复制为
    cars
    的主体

  • 第二种转换基于最基本、最强大的XSLT设计模式之一——使用并覆盖标识规则

  • 标识模板按“原样”复制每个匹配的节点(为其选择要处理的节点)

  • 有一个模板覆盖标识规则。此模板匹配任何
    汽车
    ,对于这些汽车,
    数据[@attrib='Model'和text='855']
    不正确。模板的主体是空的,这导致匹配的
    car
    元素没有复制到输出中——换句话说,我们可以说amy matching
    car
    元素被“删除”


  • 只需添加到这个响应中:这将返回所选的“car”元素。它不会按要求将其包装在“cars”元素中。由于输入不包含只有一个子元素的现有“cars”元素,因此只能通过构造新的“cars”元素来实现此输出,为此,需要使用XQuery而不是XPath,使用XSLT比使用XQuery更容易、更自然地进行此类处理。@DimitreNovatchev您能给出一个XSLT示例吗?