【问题标题】:Nokogiri condition based on attribute value基于属性值的 Nokogiri 条件
【发布时间】:2016-06-16 21:11:38
【问题描述】:

我正在尝试使用基于现有属性值的 Nokogiri 解析两个 XML 文件。问题是我的初始条件总是返回 true,即使 xpath 处不存在该节点。我认为我做的一切都是正确的,但显然我没有。

这是我的两个 XML 文件:

dnsrecon_output.xml(典型文件输出)

<?xml version="1.0" ?>
<records>
    <record ns_server="192.168.1.1" type="info" zone_transfer="failed"/>
    <record ns_server="192.168.1.2" type="info" zone_transfer="failed"/>
    <record address="192.168.1.1" mname="ns1.mynetwork.local" type="SOA"/>
    <record Version="9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.5" address="192.168.1.1" recursive="True" target="ns1.mynetwork.local" type="NS"/>
    <record Version="9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.5" address="192.168.1.2" recursive="True" target="ns2.mynetwork.local" type="NS"/>
    <record address="192.168.1.3" name="web.local" type="A"/>
</records>

dnsrecon_brute.xml

<?xml version="1.0" ?>
<records>
    <record address="192.168.1.3" name="dev.web.local" type="A"/>
    <record name="ftp.web.local" target="dev.web.local" type="CNAME"/>
    <record address="192.168.1.4" name="git.web.local" type="A"/>
    <record address="192.168.1.5" name="ops.web.local" type="A"/>
    <record address="192.168.1.6" name="whm.web.local" type="A"/>
    <record address="192.168.1.7" name="www.web.local" type="A"/>
</records>

但是,如果zone_transfer=success 输出将如下所示...

dnsrecon_output_xfer.xml(只是为了显示我要匹配的内容)

<?xml version="1.0" ?>
<records>
    <record ns_server="192.168.1.2" type="info" zone_transfer="success"/>
    <record address="192.168.1.2" mname="ns" type="SOA" zone_server="192.168.1.2"/>
    <record address="192.168.1.2" target="ns1.network.local" type="NS" zone_server="192.168.1.2"/>
    <record address="192.168.1.100" name="win.network.local" type="A" zone_server="192.168.1.2"/>
    <record address="192.168.1.2" name="ns1.network.local" type="A" zone_server="192.168.1.2"/>
    <record address="192.168.1.2" mname="ns1.network.local" type="SOA"/>
</records>

这是我的 Nokogiri 解析。主要是我想检查zone_transfer=success是否存在,如果它没有移动到*_brute.xml文件:

document = Nokogiri::XML(File.open("dnsrecon_output.xml"))

document.remove_namespaces!

# Strictly for Zone transfers
if document.xpath("//records//record[@zone_transfer='success']")
  puts "Zone Transfer Successful ... YIKES!!!"
  document.xpath("//records//record[@type='A']").each do |record|
    # change the output here to match what we need it to...
    puts "#{record.at_xpath("@address")} - #{record.at_xpath("@name")}"
  end
else
  puts "No zone transfers... moving to brute"
  document2 = Nokogiri::XML(File.open("dnsrecon_brute.xml"))
  document2.remove_namespaces!

  document2.xpath("//records//record[@type='A' or @type='CNAME']").each do |record|
    puts "#{record.at_xpath("@address")} - #{record.at_xpath("@name")}"
  end
end

如您所见,我最初解析的是dnsrecon_output.xml 文件,该文件的记录标签中包含zone_transfer="failed"。但是,我在控制台中的输出是:

Zone Transfer Successful ... YIKES!!!
192.168.1.3 - web.local

并且永远不要运行else 部分,这是应该的。属性值检查哪里出错了?

【问题讨论】:

    标签: ruby xml xpath nokogiri


    【解决方案1】:

    您的支票返回一个空的Nokogiri::XML::NodeSet,这是真实的。

    读取属性并比较其值:

    if document.xpath("//records//record/@zone_transfer").first.value == 'success'
        ...
    

    请注意,这仅在 xpath 匹配至少一个元素时才有效(因此它不适用于“brute”文件)。

    或添加any? 以获得布尔返回:

    if document.xpath("//records//record[@zone_transfer='success']").any?
        ...
    

    【讨论】:

    • 您的第一个条件不适用于空数组:first() 返回 nil,您不能在 nil 上调用 value()
    • 使用document.at 获取元素或nil
    【解决方案2】:
    x = document.xpath("//records//record[@zone_transfer='success']")
    p x
    
    --output:--
    []
    

    和:

    if []
      puts %q{It's true!}
    end
    
    --output:--
    It's true.
    

    在 ruby​​ 中评估为 false 的唯一值是 false 本身和 nil。空数组、空哈希、空字符串、0等都是真的。

    相反,您可以这样做:

    if document.xpath("//records//record[@zone_transfer='success']").empty?
      puts "no matching elements"
      #got to next xml file
    else
      puts "found matches"
      #do your other xpath search
    end
    
    --output:--
    no matching elements
    

    【讨论】:

    • xpath 查询不返回一个空数组,而是一个空的NodeSet(虽然这在 if 子句中没有区别)
    • @pascalbetz,Node 方法 xpath 和 css 实际上返回一个 NodeSet,它的行为非常像一个数组...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多