Nokogiri不加载解析整个xml文件

时间:2012-08-23 13:06:23

标签: ruby-on-rails ruby nokogiri

我有一个XML文档:

<event>
    <type>SUBSCRIPTION_ORDER</type>
    <marketplace>
        <baseUrl>https://www.acme-marketplace.com</baseUrl>
        <partner>ACME</partner></marketplace>
    </marketplace>
    <creator>
        <email>admin@fakeco</email>
        <firstName>Alice</firstName>
        <lastName>Hacker</lastName>
        <openId>https://www.acme-marketplace.com/openid/id/a11a7918-bb43-4429-a256-f6d729c71033</openId>
        <uuid>a11a7918-bb43-4429-a256-f6d729c71033</uuid>
    </creator>
    <payload>
        <company>
            <uuid>d15bb36e-5fb5-11e0-8c3c-00262d2cda03</uuid>
            <email>admin@fakeco</email>
            <name>Fake Co.</name>
            <phoneNumber>1-415-555-1212</phoneNumber>
            <website>fakeco</website>
        </company>
        <order>
            <editionCode>BASIC</editionCode>
            <item>
                <quantity>10</quantity>
                <unit>USER</unit>
            </item>
        </order>
    </payload>
</event>

当我用nokogiri加载它时,我得到了奇怪的结果:

1.9.3p194 :056 > doc = Nokogiri::XML(File.open("test.xml")).to_s
=> "<?xml version=\"1.0\"?>\n<event>\n    <type>SUBSCRIPTION_ORDER</type>\n    <marketplace>\n        <baseUrl>https://www.acme-marketplace.com</baseUrl>\n        <partner>ACME</partner></marketplace>\n    </event>\n"

我做错了什么?

2 个答案:

答案 0 :(得分:3)

您有两个关闭</marketplace>标记,这是无效的XML:

    <partner>ACME</partner></marketplace>
</marketplace>

删除其中一个,Nokogiri应该正确读取文件。

答案 1 :(得分:1)

如果您将XML解析为Nokgiri :: XML文档:

doc = Nokogiri::XML(<<EOT)
<event>
    <type>SUBSCRIPTION_ORDER</type>
    <marketplace>
        <baseUrl>https://www.acme-marketplace.com</baseUrl>
        <partner>ACME</partner></marketplace>
    </marketplace>
    <creator>
        <email>admin@fakeco</email>
        <firstName>Alice</firstName>
        <lastName>Hacker</lastName>
        <openId>https://www.acme-marketplace.com/openid/id/a11a7918-bb43-4429-a256-f6d729c71033</openId>
        <uuid>a11a7918-bb43-4429-a256-f6d729c71033</uuid>
    </creator>
    <payload>
        <company>
            <uuid>d15bb36e-5fb5-11e0-8c3c-00262d2cda03</uuid>
            <email>admin@fakeco</email>
            <name>Fake Co.</name>
            <phoneNumber>1-415-555-1212</phoneNumber>
            <website>fakeco</website>
        </company>
        <order>
            <editionCode>BASIC</editionCode>
            <item>
                <quantity>10</quantity>
                <unit>USER</unit>
            </item>
        </order>
    </payload>
</event>
EOT

然后检查文档的errors方法,您会看到:

doc.errors
[
    [0] #<Nokogiri::XML::SyntaxError:0x100a6dbb8
        attr_reader :code = 76,
        attr_reader :column = 19,
        attr_reader :domain = 1,
        attr_reader :file = nil,
        attr_reader :int1 = 1,
        attr_reader :level = 3,
        attr_reader :line = 6,
        attr_reader :str1 = "event",
        attr_reader :str2 = "marketplace",
        attr_reader :str3 = nil
    >,
    [1] #<Nokogiri::XML::SyntaxError:0x100a6daa0
        attr_reader :code = 5,
        attr_reader :column = 5,
        attr_reader :domain = 1,
        attr_reader :file = nil,
        attr_reader :int1 = 0,
        attr_reader :level = 3,
        attr_reader :line = 7,
        attr_reader :str1 = nil,
        attr_reader :str2 = nil,
        attr_reader :str3 = nil
    >
]

那是Nokogiri告诉你文件的问题。您可以使用以下方式对此做出足够的反应:

if (!doc.errors.empty?)
  ...
end

由于在RECOVER步骤中设置了parse标记,它尝试从错误中恢复,但在某些情况下它无法修复,例如加倍的结束标记。在Nokogiri能够理解之前,您需要进行飞行前检查并修复以清理文档。不幸的是,并非所有XML都是正确生成的,并且创建它的人应该在将其放入之前通过有效性检查器运行它。因此,它在XML世界中不符合并被认为是非法的。