如何有条件地访问XML参数

时间:2014-11-09 20:07:56

标签: ruby xml parsing rexml

这是一个XML代码段:

<testcase name="T.3.03.02">
    <cmd>CMD_EXPORT_RAM_KEY</cmd>
    <sreg_pre>40</sreg_pre>
    <sreg_pre_bitmask>ff</sreg_pre_bitmask>
    <sreg_post>40</sreg_post>
    <sreg_post_bitmask>ff</sreg_post_bitmask>
    <erc>ERC_NO_ERROR</erc>
    <testvector>
        <parameter name="UID" type="info">000000000000000000000000000002</parameter>
        <parameter name="UID'" type="info">000000000000000000000000000002</parameter>
        <parameter name="KeyId" type="info">0e</parameter>
        <parameter name="Key" type="info">0f0e0d0c0b0a09080706050403020100</parameter>
        <parameter name="AuthId" type="info">00</parameter>
        <parameter name="KeyAuth" type="info">2b7e151628aed2a6abf7158809cf4f3c</parameter>
        <parameter name="Old counter value of updated key slot" type="info">0000000</parameter>
        <parameter name="New counter value C'" type="info">0000000</parameter>
        <parameter name="Protection flags F'" type="info">00</parameter>
        <parameter name="M1" type="output">000000000000000000000000000002e0</parameter>
        <parameter name="M2" type="output">152876f29dc7ca8d18e38d70374492b05d908c8c584a0409849a553c75254def</parameter>
        <parameter name="M3" type="output">bc6e79bc4458339174fc80fb08b83188</parameter>
        <parameter name="M4" type="output">000000000000000000000000000002e07783b86ae87b87e3ca12809c2df75fae</parameter>
        <parameter name="M5" type="output">c8fcc8859c69c8bd840ce8e24c5114e9</parameter>
    </testvector>
    <precondition>RAM_KEY_PLAIN = 1; RAM_KEY_EMPTY = 0</precondition>
    <description>Export plain RAM_KEY with external debugger attached; Note: The security flags SECURE_BOOT_PROTECTION and DEBUGGER_PROTECTION of the key SECRET_KEY are inherited from MASTER_ECU_KEY.</description>
</testcase>

我想访问所有"parameter name="Key" type="info"值。

如果条件<cmd>CMD_EXPORT_RAM_KEY(second line in XML)</cmd>有效,如何有条件地访问这些值。

在这个XML文件中,还有其他命令(<cmd>行)也带有&#34; Key&#34;参数, 但在这些情况下,我并不想获得关键值。

我没有让它运行。

任何人都可以帮我一些想法吗?

3 个答案:

答案 0 :(得分:0)

这样的事情会起作用吗?

  doc = Nokogiri::parse(File.read( "data.xml" ))
  check = doc.xpath( "//cmd" ).select{|el| el.children[0].text == "CMD_EXPORT_RAM_KEY" }
  puts "Check: %i" % check.size
  if(check.size == 0)
    ## Do stuff here
  end

答案 1 :(得分:0)

使用Nokogiri尝试下面的XPath:

//testcase/cmd[text()='CMD_EXPORT_RAM_KEY']/../testvector/parameter[@name="Key" and @type="info"]

当然,您可以参数化CMD_EXPORT_RAM_KEY@name / @type值。

答案 2 :(得分:0)

诀窍是使用选择器找到您想要的特定部分,然后在必要时进一步缩小范围。

使用CSS选择器'parameter[@name="Key"][@type="info"]' Nokogiri可以轻松找到样本中的单个选择。如果还有更多,那么将返回更多:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<testcase name="T.3.03.02">
    <testvector>
        <parameter name="UID" type="info">000000000000000000000000000002</parameter>
        <parameter name="Key" type="info">0f0e0d0c0b0a09080706050403020100</parameter>
    </testvector>
</testcase>
EOT

doc.search('parameter[@name="Key"][@type="info"]').map(&:content)
# => ["0f0e0d0c0b0a09080706050403020100"]

我使用CSS,因为它看起来不像线路噪声,而不是等效的XPath选择器。

此外,在提供样本数据时,请将其降低到测试代码所需的最低限度。除此之外的任何东西都会浪费我们的时间,而且,如果它太多,实际上可能会导致你没有得到答案,因为没有人愿意趟过它。