我有一个XML转储,我试图用Nokogiri
解析它以获取属性的文本值,然后找出它是否与我正在寻找的某个字符串匹配。这是我的XML文件的片段:
#(Element:0x3fc58cc091f8 {
name = "host",
attributes = [ #(Attr:0x3fc58cc08528 { name = "starttime", value = "1481896934" }), #(Attr:0x3fc58cc08514 { name = "endtime", value = "1481896947" })],
children = [
#(Element:0x3fc58af6bdc0 {
name = "status",
attributes = [
#(Attr:0x3fc58af6b6f4 { name = "state", value = "up" }),
#(Attr:0x3fc58af6b6e0 { name = "reason", value = "arp-response" }),
#(Attr:0x3fc58af6b6cc { name = "reason_ttl", value = "0" })]
}),
#(Text "\n"),
#(Element:0x3fc58a744fe8 {
name = "os",
children = [
#(Element:0x3fc58c1392f0 {
name = "osmatch",
attributes = [
#(Attr:0x3fc58c1381d4 { name = "name", value = "Microsoft Windows XP SP2 or SP3, or Windows Server 2003" }),
#(Attr:0x3fc58c1381c0 { name = "accuracy", value = "100" }),
#(Attr:0x3fc58c1381ac { name = "line", value = "57766" })],
children = [
#(Text "\n"),
#(Element:0x3fc58ae89e70 {
name = "osclass",
attributes = [
#(Attr:0x3fc58ae893bc { name = "type", value = "general purpose" }),
#(Attr:0x3fc58ae893a8 { name = "vendor", value = "Microsoft" }),
#(Attr:0x3fc58ae89394 { name = "osfamily", value = "Windows" }),
#(Attr:0x3fc58ae89380 { name = "osgen", value = "XP" }),
#(Attr:0x3fc58ae8936c { name = "accuracy", value = "100" })],
children = [ #(Element:0x3fc58b19428c { name = "cpe", children = [ #(Text "cpe:/o:microsoft:windows_xp")] })]
}),
#(Text "\n"),
所以,我尝试做的是获取os/osmatch/@name.value
的内容。在这种情况下,它将是Windows XP SP2 or SP3, or Windows Server 2003
。
我已经把那部分放下了:
doc.xpath("//host").each do |host|
os = host.at_xpath("os/osmatch").at_xpath("@name").value rescue nil
end
output: Microsoft Windows XP SP2 or SP3, or Windows Server 2003
通常,我的XML文件将拥有大量具有不同操作系统的主机,因此输出可能类似于:
Microsoft Windows XP SP2 or SP3, or Windows Server 2003
Ubuntu 14.04 Linux
Microsoft Windows 7, or Microsoft Windows 8
FreeBSD X.X.X
....
我尝试做的是将某些字符串与我现在正在寻找的值匹配,因此如果找到Windows XP
,我可以采取一些措施。
doc.xpath("//host").each do |host|
os = host.at_xpath("os/osmatch").at_xpath("@name[contains(value, 'Windows XP')]")
end
但相反,我收到了错误,所以我知道我做错了什么。我尝试过其他一些变体,但无法弄清楚如何做到这一点:
Nokogiri::XML::XPath::SyntaxError: Invalid expression: @name[contains(value, 'Windows']
答案 0 :(得分:1)
您似乎在混淆Xpath和Ruby代码。您的工作代码是
at_xpath("@name").value
这里@name
是XPath查询,这会向Ruby返回一个Node
对象。此对象具有value
方法,该方法以字符串形式返回属性的值,但value
不有效的XPath。
您尝试通过添加谓词来更改此内容:
at_xpath("@name[contains(value, 'Windows XP')]")
在这里,您尝试在XPath中使用Ruby value
方法。这不起作用。但是,在XPath中,您可以使用.
(即点)来选择当前节点,这就是您想要的:
at_xpath("@name[contains(., 'Windows XP')]")
如果它包含字符串“Windows XP”,这将为您提供当前节点的name
属性(您正在调用at_xpath
的内容)。
答案 1 :(得分:0)
host.at_xpath("os/osmatch[contains(@name,'Windows')]")