2016-12-16 7 views
0

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ファイルは、しかし異なるのOSとホストのトンを持っていますので、出力は可能性のようなものになります。

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'] 
+1

パースされた結果の出力ではなく、実際のXMLの例を挙げて、問題を再現してソリューションをテストできるようにしてください。 – matt

+0

@matt申し訳ありません...それは本当に長いです。目を救おうとしている! – Godzilla74

+1

"目を救おうとしていて、本当に長かったです!" "[mcve]"をお読みください。感想はありがたいですが、投稿する前に問題を示す最小限の量まで入力XMLを削除する必要があります。あなたのコードと入力を取り除くそのプロセスは、質問をする必要なしにあなたに問題を明らかにすることがよくあります。そして、@mattが述べたように、XMLは私たちにとって有益です。検査されたDOMは、ソリューションをテストするために再利用することができないほど有用ではありません。それは私たちがあなたを助けるためにあなたが必要なことです。 –

答えて

0
host.at_xpath("os/osmatch[contains(@name,'Windows')]") 
+0

これは、要素全体を返します。私は返すために '@ name'値を取得する必要があります。 – Godzilla74

+0

これまでのようにさらに質問してください。 xpath要素です。 – mudasobwa

+0

ああ、つかまえ!ありがとう! – Godzilla74

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')]") 

これはあなたの現在のノード(事あなた」のname属性を与えます文字列 "Windows XP"が含まれている場合はat_xpathを呼び出してください)。

関連する問題