У меня есть дамп XML и я пытаюсь его проанализировать с помощью Nokogiri
, чтобы получить текстовое значение атрибута, а затем выяснить, соответствует ли он определенной строке, которую я ищу. Вот отрывок из моего файла XML:Получение значения атрибута и тестирование его с помощью Nokogiri
#(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']
Вероятно, вы должны привести пример фактического XML, а не результат анализируемого результата, чтобы люди могли воспроизводить ваши проблемы и тестовые решения. – matt
@matt Извините ... это было очень долго. пытаясь спасти глаза! – Godzilla74
«Это было очень долго, пытаясь спасти глаза!» Пожалуйста, прочитайте «[mcve]». Мы ценим настроение, но вам нужно лишить входной XML до минимальной суммы, которая демонстрирует проблему до публикации. Этот процесс снятия кода и ввода часто выявляет проблему для вас без необходимости задавать вопрос. И, как сказал @matt, XML полезен для нас. Проверенный DOM не так полезен, поскольку мы не можем его повторно использовать для тестирования решений. Что это значит, нам нужно, чтобы вы помогли нам помочь вам. –