ruby - XPath 只选择子元素(不是空白文本节点)

标签 ruby xml xpath nokogiri

我正在使用 Nokogiri 和 XPath 解析一些 XML。当我这样做时:

doc.xpath('//Order/child::node()').each do |node|
  puts node.name
end

它打印出所有节点,但也在名称之间打印出“文本”。我想我知道为什么:

在我的 xml 中,节点之间有这样的空格:"<a1>hi</a1> \n <a2>bye</a2>"

有没有办法告诉它忽略节点之间的内容?

最佳答案

使用:

//Order/node()[not(self::text()[not(normalize-space())])]

这会选择任何 Order 元素的所有子节点,除了那些完全由空白组成的文本节点。

基于 XSLT 的验证:

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


 <xsl:template match="/*">
     <xsl:variable name="vSel1" select="//Order/node()"/>
     <xsl:variable name="vSel2" select=
     "//Order/node()[not(self::text()[not(normalize-space())])]"/>

     <xsl:for-each select="$vSel1">
       <xsl:value-of select="concat('&#xA;',position(), ': ')"/>
       <xsl:copy-of select="."/>
       <xsl:text>&#xA;</xsl:text>
     </xsl:for-each>
================
     <xsl:for-each select="$vSel2">
       <xsl:value-of select="concat('&#xA;',position(), ': ')"/>
       <xsl:copy-of select="."/>
       <xsl:text>&#xA;</xsl:text>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时:

<t>
 <Order>
  <a/>
  <b>xxx</b>
  <c/>
 </Order>
 <Order>
  <d/>
  <e>xxx</e>
  <f/>
 </Order>
</t>

计算两个 XPath 表达式并输出两组相应的选定节点的节点,每个节点前面都有其位置编号:

1: 


2: <a/>

3: 


4: <b>xxx</b>

5: 


6: <c/>

7: 


8: 


9: <d/>

10: 


11: <e>xxx</e>

12: 


13: <f/>

14: 


================

1: <a/>

2: <b>xxx</b>

3: <c/>

4: <d/>

5: <e>xxx</e>

6: <f/>

关于ruby - XPath 只选择子元素(不是空白文本节点),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8889450/

相关文章:

java - 了解简单 XML 解析器 - 新文件输出 - Java

java - 如何在没有本地 XSD 文件的情况下根据 XML 架构验证 XML?

xml - 如何在xsl:apply-templates select属性中使用或声明?

xml - 使用命名空间属性和 SelectSingleNode 属性的 XPATH

java - 获取子标签具有属性 x 的属性

mysql - 是否有更有效的方法根据每个记录有多少关联来对数组进行排序?

ruby - 使用 Regexp 部分匹配 Ruby 字符串的方法

ruby - 如何在 ruby​​ 1.8 中用 ascii 替换 unicode 引号?

javascript - JavaScript 中不区分大小写的 XPath 节点匹配

ruby-on-rails - Rails 试图创建嵌套路由