Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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
Ruby 搜索XML并获取作为XML的节点子集_Ruby_Xml_Search_Xpath_Nokogiri - Fatal编程技术网

Ruby 搜索XML并获取作为XML的节点子集

Ruby 搜索XML并获取作为XML的节点子集,ruby,xml,search,xpath,nokogiri,Ruby,Xml,Search,Xpath,Nokogiri,给定一个搜索词,如何搜索XML中节点的属性并返回XML,该XML只包含与该词匹配的节点及其父节点,一直跟踪到根节点 以下是输入XML的示例: <root> <node name = "Amaths"> <node name = "Bangles"/> </node> <node name = "C"> <node name = "Dangles"> <node name =

给定一个搜索词,如何搜索XML中节点的属性并返回XML,该XML只包含与该词匹配的节点及其父节点,一直跟踪到根节点

以下是输入XML的示例:

<root>
  <node name = "Amaths"> 
    <node name = "Bangles"/> 
  </node>
  <node name = "C">
    <node name = "Dangles">
      <node name = "E"> 
        <node name = "Fangles"/> 
      </node>
    </node>
    <node name = "Gdecimals" />
  </node>
  <node name = "Hnumbers"/> 
  <node name = "Iangles"/> 
</root>

我正在寻找搜索词“角度”的输出:


我用来搜索xml的XPath是“/*[contains(@name,'angles')]”“

我在Ruby中使用Nokogiri来搜索XML,它为我提供了一个匹配该术语的所有节点的节点集。我不知道如何从这组节点构造回XML

谢谢

编辑:修复了该示例应已修复的问题。谢谢你,迪米特


编辑2:再次修复xml格式是否正确。

首先,请注意显示的所需输出不正确,并且以下元素在文档后面没有结束标记:

<node name = "C">
但是,节点不会更改,并且它们包含所有子节点,这意味着根在
Root
中的完整子树仍然是返回结果中
Root
的子树

如果您想要获得与原始XML文档结构不同的新文档(节点集),则必须使用承载XPath的另一种语言。有许多这样的语言,如XSLT、XQuery和任何带有XMLDOM实现的语言

这里是一个XSLT转换,生成所需的结果

<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="*[not(descendant-or-self::*[contains(@name, 'angles')])]"/>
</xsl:stylesheet>
<root>
  <node name = "Amaths">
    <node name = "Bangles"/>
  </node>
  <node name = "C">
    <node name = "Dangles">
      <node name = "E">
        <node name = "Fangles"/>
      </node>
      <node name = "Gdecimals" />
    </node>
  </node>
  <node name = "Hnumbers"/>
  <node name = "Iangles"/>
</root>
<root>
   <node name="Amaths">
      <node name="Bangles"/>
   </node>
   <node name="C">
      <node name="Dangles">
         <node name="E">
            <node name="Fangles"/>
         </node>
      </node>
   </node>
   <node name="Iangles"/>
</root>

在提供的XML文档上应用此转换时(更正为格式正确)

<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="*[not(descendant-or-self::*[contains(@name, 'angles')])]"/>
</xsl:stylesheet>
<root>
  <node name = "Amaths">
    <node name = "Bangles"/>
  </node>
  <node name = "C">
    <node name = "Dangles">
      <node name = "E">
        <node name = "Fangles"/>
      </node>
      <node name = "Gdecimals" />
    </node>
  </node>
  <node name = "Hnumbers"/>
  <node name = "Iangles"/>
</root>
<root>
   <node name="Amaths">
      <node name="Bangles"/>
   </node>
   <node name="C">
      <node name="Dangles">
         <node name="E">
            <node name="Fangles"/>
         </node>
      </node>
   </node>
   <node name="Iangles"/>
</root>

生成所需(正确)结果

<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="*[not(descendant-or-self::*[contains(@name, 'angles')])]"/>
</xsl:stylesheet>
<root>
  <node name = "Amaths">
    <node name = "Bangles"/>
  </node>
  <node name = "C">
    <node name = "Dangles">
      <node name = "E">
        <node name = "Fangles"/>
      </node>
      <node name = "Gdecimals" />
    </node>
  </node>
  <node name = "Hnumbers"/>
  <node name = "Iangles"/>
</root>
<root>
   <node name="Amaths">
      <node name="Bangles"/>
   </node>
   <node name="C">
      <node name="Dangles">
         <node name="E">
            <node name="Fangles"/>
         </node>
      </node>
   </node>
   <node name="Iangles"/>
</root>


好问题(+1)。有关解释和简单的XSLT解决方案,请参见我的答案。@Dimitre:非常感谢!关于输出中的错误,我已经解决了这个问题。将尝试您的解决方案并让您知道。再次感谢。@Vijay Dev:XML文档的格式仍然不正确。我已更改了答案,以包含您最新的XML文档(已更正为格式正确)和新结果。@Dimitre:您介意回答一个变体吗?我需要在输出xml中包含与搜索词匹配的节点的所有子节点,不管它们的“name”属性是什么。如何修改XPath以实现这一点?谢谢@Vijay Dev:如果我理解的很好,这是我回答中的第一个XPath表达式。编写了另一个xsl:template来匹配“*[(祖先或自我::*[contains(@name,\'angles\'))]”似乎可以正常工作。如果有更好的办法,请告诉我。