gpt4 book ai didi

ruby - 如何使用 nokogiri 打印所有非空白 XML 节点的值及其标签名称?

转载 作者:数据小太阳 更新时间:2023-10-29 08:18:38 25 4
gpt4 key购买 nike

这是我的 sample.xml:

<?xml version="1.0" encoding="utf-8"?>
<ShipmentRequest>
<Message>
<Header>
<MemberId>MID-0000001</MemberId>
<MemberName>Bruce</MemberName>
<DeliveryId>0000001</DeliveryId>
<OrderNumber>ON-000000001</OrderNumber>
<ShipToName>Alan</ShipToName>
<ShipToZip>123-4567</ShipToZip>
<ShipToStreet>West</ShipToStreet>
<ShipToCity>Seatle</ShipToCity>
<Payments>
<PayType>Credit Card</PayType>
<Amount>20</Amount>
</Payments>
<Payments>
<PayType>Points</PayType>
<Amount>22</Amount>
</Payments>
<PayType />
</Header>
<Line>
<LineNumber>3.1</LineNumber>
<ItemId>A-0000001</ItemId>
<Description>Apple</Description>
<Quantity>2</Quantity>
<UnitCost>5</UnitCost>
</Line>
<Line>
<LineNumber>4.1</LineNumber>
<ItemId>P-0000001</ItemId>
<Description>Peach</Description>
<Quantity>4</Quantity>
<UnitCost>6</UnitCost>
</Line>
<Line>
<LineNumber>5.1</LineNumber>
<ItemId>O-0000001</ItemId>
<Description>Orange</Description>
<Quantity>2</Quantity>
<UnitCost>4</UnitCost>
</Line>
</Message>
</ShipmentRequest>

还有我的 sample.rb:

#!/usr/bin/ruby -w

require 'nokogiri'

doc = Nokogiri::XML(open("sample.xml"))
doc.xpath("//ShipmentRequest").each {
|node| puts node.text
}

我得到的结果:

MID-0000001    
Bruce
0000001
ON-000000001
Alan
123-4567
West
Seatle

Credit Card
20


Points
22




3.1
A-0000001
Apple
2
5


4.1
P-0000001
Peach
4
6


5.1
O-0000001
Orange
2
4

我还想打印标签名称并跳过具有空白值的标签/节点:

MemberID: MID-0000001

MemberName: Bruce

DeliveryId: 0000001

OrderNumber: ON-000000001

ShipToName: Alan

ShipToZip: 123-4567

ShipToStreet: West

etc...

最佳答案

您基本上需要所有叶元素。您可以在一个 XPath 表达式中捕获所有这些:

leaves = doc.xpath('//*[not(*)]')

leaves.each do |node|
puts "#{node.name}: #{node.text}" unless node.text.empty?
end

输出:

MemberId: MID-0000001
MemberName: Bruce
DeliveryId: 0000001
OrderNumber: ON-000000001
ShipToName: Alan
ShipToZip: 123-4567
ShipToStreet: West
ShipToCity: Seatle
PayType: Credit Card
Amount: 20
PayType: Points
Amount: 22
LineNumber: 3.1
ItemId: A-0000001
Description: Apple
Quantity: 2
UnitCost: 5
LineNumber: 4.1
ItemId: P-0000001
Description: Peach
Quantity: 4
UnitCost: 6
LineNumber: 5.1
ItemId: O-0000001
Description: Orange
Quantity: 2
UnitCost: 4

XPath的解释

XPath //*[not(*)] 找到所有叶元素。它是如何做到的?让我们分解一下:

  • // 表示扫描整个文档。
  • *表示任意元素,所以//*匹配文档中的所有元素。
  • [] 中的部分称为谓词,它约束前面的表达式。我读它就像一个“那样”。它的范围是元素的子元素,例如 a[b] 表示所有 a 元素,这样它们就有一个 b 子元素。
  • not() 只是一个 bool 否定,所以 not(*) 表示“没有元素”,因此在谓词中它表示“没有子元素”。

将它们放在一起,您拥有“文档中的所有元素,它们没有任何子元素”== 叶元素。

另一个版本

在评论中,@Phrogz 做了一个很好的补充,通过添加另一个谓词将检查元素是否为空的逻辑移动到 XPath 表达式。这有两个好处:

  • 它会提高性能,因为它不会返回所有叶子然后检查它们。这在大型文档或有很多空白页的情况下可能会很明显。
  • 它变成了一条线!

puts doc.xpath('//*[not(*)][text()]').map{ |n| "#{n.name}: #{n.text}"}

意思是“每个没有子元素但至少有一个子文本节点的元素。”

关于ruby - 如何使用 nokogiri 打印所有非空白 XML 节点的值及其标签名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16852631/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com