【发布时间】:2014-07-04 15:35:00
【问题描述】:
我正在尝试使用 Nokogiri 从 XML 中提取值。
我想将具有相同名称但不同 xpath 的子元素存储在一个数组中。这些元素是ProdA、ProdB。
目前我只尝试打印子元素,但到目前为止我的代码只打印“SDocument”而不是子元素。
目标是有一个这样的数组:
array = [["2","8"], ["8","9"]]
这是代码:
#!/usr/bin/env ruby
require 'nokogiri'
doc = Nokogiri::XML(File.open("input.xml"))
a = doc.xpath("//SDocument").each do |n|
n if n.text?
end
puts a
这是 XML:
<?xml version="1.0" encoding="UTF-8"?>
<Document-St-5>
<SDocument>
<ItemList>
<Items_A>
<ItemElem>
<Item_Values>
<ProdA>2</ProdA>
<ProdB>8</ProdB>
</Item_Values>
</ItemElem>
</Items_A>
<Items_B>
<ItemElem>
<Item_Values>
<ProdA>8</ProdA>
<ProdB>9</ProdB>
</Item_Values>
</ItemElem>
</Items_B>
</ItemList>
</SDocument>
</Document-St-5>
有人可以指点我正确的方法吗?
更新:
我真正想要的是在一个数组中存储 SDocument 节点的所有唯一子元素的 XPath 以及具有多个
发生,将它们分组存储。但如果可能在不知道孩子名称的情况下获取 XPath,则只获取唯一的 XPath。
例如:
子元素StName 和StCode 各只出现一次,那么目前有XPath 的数组将是:
arr_Xpath = [ ["/Document-St-5/SDocument/StName"], ["/Document-St-5/SDocument/StCode"], ... ]
作为节点 Items_A 子节点的 ProdA 节点具有以下 XPath:
/Document-St-5/SDocument/ItemList/Items_A/ItemElem/Item_Values/ProdA
作为节点 Items_B 子节点的 ProdA 节点具有以下 XPath:
/Document-St-5/SDocument/ItemList/Items_B/ItemElem/Item_Values/ProdA
那么子元素的唯一 XPath 数组将是(包括 ProdB 节点的 XPath):
arr_Xpath = [ "/Document-St-5/SDocument/StName",
"/Document-St-5/SDocument/StCode",
"/Document-St-5/SDocument/ItemList/Items_A/ItemElem/Item_Values/ProdA",
"/Document-St-5/SDocument/ItemList/Items_A/ItemElem/Item_Values/ProdB",
"/Document-St-5/SDocument/ItemList/Items_B/ItemElem/Item_Values/ProdA",
"/Document-St-5/SDocument/ItemList/Items_B/ItemElem/Item_Values/ProdB" ]
我认为,首先了解唯一的 XPath,可以使用 doc.xpath("..") 获取每个子元素的值并将它们分组
如果它不止一次出现。所以,我想得到的最终数组是:
arr_Values = [ ["WERLJ01"], ["MEKLD"],["2","9"],["8","3"],["1"],["17"]]
地点:
-
arr_Values[0]是包含StName值的数组 -
arr_Values[1]是包含StCode值的数组 -
arr_Values[2]是包含ProdA节点的所有Items_A子节点值的数组。 -
arr_Values[3]是包含ProdB节点的所有Items_A子节点值的数组。 -
arr_Values[4]是包含ProdA节点的所有Items_B子节点的值的数组。 -
arr_Values[5]是包含Items_B的所有ProdB节点的子节点值的数组。
一个 XML 示例是:
<?xml version="1.0" encoding="UTF-8"?>
<Document-St-5>
<SDocument>
<StName>WERLJ01</StName>
<StCode>MEKLD</StCode>
<ItemList>
<Items_A>
<ItemElem>
<Item_Values>
<ProdA>2</ProdA>
<ProdB>8</ProdB>
</Item_Values>
</ItemElem>
</Items_A>
<Items_A>
<ItemElem>
<Item_Values>
<ProdA>9</ProdA>
<ProdB>3</ProdB>
</Item_Values>
</ItemElem>
</Items_A>
<Items_B>
<ItemElem>
<Item_Values>
<ProdA>1</ProdA>
<ProdB>17</ProdB>
</Item_Values>
</ItemElem>
</Items_B>
</ItemList>
</SDocument>
</Document-St-5>
更新 2:
你好,铁皮人,它有效! “%w”和“%w[element1 element2]”是什么意思? %w[...] 表单是否接受超过 2 个元素?
我是 Nokogiri 的新手,我只提到 Xpath,因为 XML 有 200 多个唯一的子节点(唯一的 Xpath),那么你建议我对所有子节点使用与 CSS 相同的技术还是有办法处理XML 并在不知道子节点名称的情况下执行相同操作(将具有相同名称和相同 Xpath 的元素分组到数组中)?我想知道你建议我的方式。
再次感谢
【问题讨论】:
-
人们/回答者使用 XPaths 还是 CSS 作为访问器有什么区别? XPaths,尤其是您展示过的 XPaths,将不那么灵活而且更冗长。指定节点的完整路径也会让你的代码更加脆弱;对 XML 结构的更改会破坏您的应用程序。相反,使用地标来定位您想要的数据。