【问题标题】:Retrieve a value from the first node in an XML::Nodeset using Crystal使用 Crystal 从 XML::Nodeset 中的第一个节点检索值
【发布时间】:2015-09-18 12:15:25
【问题描述】:

我正在使用 Crystal,并试图在 XML 文档中检索节点的 ID:

<foo ID="bar"></foo>

我正在使用以下代码获取 ID

require "xml"
file = File.read("path/to/doc.xml")
xml = XML.parse(file)
xpath_context = XML::XPathContext.new(xml)
nodeset = xpath_context.evaluate("//foo/@ID")

如果我检查节点集,我会得到我期望的内容:

[#&lt;XML::Attribute:0x1287690 name="ID" value="bar"&gt;]

nodeset.class 返回具有an instance method []XML::NodeSet。所以我相信我应该能够做到这一点来获得价值:

node = nodeset[0]
node.value

但是,当我调用 nodeset[0] 时,我收到以下错误:

undefined method '[]' for Float64 (compile-time type is (String | Float64 | Bool | XML::NodeSet))

    node = nodeset[0]

inspectclass 都将其视为XML::Nodeset 时,我不明白为什么[] 方法将nodeset 视为Float64。

我错过了什么?

String有[]方法,而Float64没有,是不是巧合?

【问题讨论】:

    标签: xml xpath crystal-lang


    【解决方案1】:

    当您执行evaluate 时,返回类型是所有可能值的联合类型。在这种情况下,XML::NodeSet 是运行时类型(注意与编译时类型的区别)。

    如果您可以确保返回类型始终是节点集,那么您可以简单地这样做:

    nodeset = xpath_context.evaluate("//foo/@ID") as XML::NodeSet
    

    但是,如果结果具有不同的类型,则会引发异常。 另一种选择是有条件地这样做:

    if nodeset.is_a?(XML::NodeSet)
        # use nodeset here without casting, the compiler will restrict the type
    end
    

    甚至使用case 声明:

    case nodeset
    when XML::NodeSet
      # ...
    end
    

    【讨论】:

    • 您还可以使用 xpath 方法和 xpath_nodes(或相关名称)来避免强制转换(将通过该方法完成)。例如:play.crystal-lang.org/#/r/fwa
    • 啊!我得到它。由于evaluate 可以返回许多不同类型的对象,编译器会通过它们中的每一个来尝试获得结果。
    • 谢谢@asterite。 xpath_nodes 看起来是一个更好的方法 - 但我很高兴我提出了这个问题,因为它帮助我更好地理解了水晶。
    • 其实 - 对于我的要求 xpath_node 更好。
    【解决方案2】:

    为了完整起见,这是我在@asterite 和@waj 的帮助下最终得到的代码

    file = File.read("path/to/doc.xml")
    xml = XML.parse(file)
    node = xml.xpath_node("//foo/@ID")
    node.text
    

    注意 node.value 也是错误的!

    【讨论】:

    • 由于我们还不是 1.0.0,所以有许多类型发生了变化并且没有记录。我们希望一旦记录了这些类型,就会更容易找到这种功能:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    相关资源
    最近更新 更多