我正试图用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
node的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]
是包含Items_A
的所有ProdA
节点子节点的值的数组 . -
arr_Values[3]
是包含Items_A
的所有ProdB
节点子节点的值的数组 . -
arr_Values[4]
是包含Items_B
的所有ProdA
节点子节点的值的数组 . -
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>
Update 2:
你好锡人,它的作品! “%w”和“%w [element1 element2]”是什么意思?表单%w [...]是否接受超过2个元素?
我是Nokogiri的新手,我只提到Xpath,因为XML有超过200个独特的子节点(独特的Xpath),那么你建议我对所有子节点使用相同的CSS技术,或者有办法处理XML和在不知道子节点名称的情况下,做同样的事情(数组中具有相同名称且具有相同Xpath的元素)?我想知道你建议我的方式 .
再次感谢
1 回答
这是一种方式:
它导致嵌套比你想要的更深,但它很接近 .
一种稍微不同的方式,或许更容易理解,是:
嵌套比您指定的更深一层的原因是,我假设XML中会有多个
<SDocument>
标记 . 如果有赢得't be, then the code can be modified a bit to return the array as you'问:请注意我正在使用CSS选择器,以便于指定我希望代码查看两个不同的节点,包括
Items_A
和Items_B
,以及ProdA
和ProdB
.问题彻底改变后更新:
这是设置:
这是代码:
这是捕获的内容: