我使用Nokogiri和XPath解析一些XML。當我這樣做:XPath只選擇子元素(不是空白文本節點)
doc.xpath('//Order/child::node()').each do |node|
puts node.name
end
它打印出的所有節點,而且在名稱之間,它打印出「文」。我想我知道爲什麼:
在我的XML,有這樣的節點之間的空間:"<a1>hi</a1> \n <a2>bye</a2>"
有沒有一種方法,我可以告訴它忽略節點之間的東西?
我使用Nokogiri和XPath解析一些XML。當我這樣做:XPath只選擇子元素(不是空白文本節點)
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('
',position(), ': ')"/>
<xsl:copy-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
================
<xsl:for-each select="$vSel2">
<xsl:value-of select="concat('
',position(), ': ')"/>
<xsl:copy-of select="."/>
<xsl:text>
</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/>
如果你只想要的元素,使用一個更好的XPath:要求/*
會找到你所有的孩子元素:
require 'nokogiri'
doc = Nokogiri.XML("<r><a>1</a>\n\t<b>2</b></r>")
p doc.xpath('/r/child::node()').map(&:name)
#=> ["a", "text", "b"]
p doc.xpath('/r/*').map(&:name)
#=> ["a", "b"]
或者,你可以要求引入nokogiri扔掉任何文本筆記只有空白:
doc2 = Nokogiri.XML("<r><a>1</a>\n\t<b>2</b></r>",&:noblanks)
p doc2.xpath('/r/child::node()').map(&:name)
#=> ["a", "b"]
或者,你可以使用Ruby還基於武斷的標準來過濾節點集:
mine = doc.xpath('/r/child::node()').select do |node|
node.type != Nokogiri::XML::Node::TEXT_NODE || node.content =~ /\S/
end
p mine.map(&:name)
#=> ["a", "b"]
您是否想要保留''的任何非元素(文本)子元素?任何評論節點? (將來,提供XML的實際測試樣本和所需的輸出將有助於您獲得更好的結果。) –
Phrogz
2012-01-17 04:23:36
*元素*之間的文本(包括空格)也是*節點*。你想找到的只是元素。 – 2012-01-18 02:06:51