3

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

ノードセットを調べると、期待どおりのコンテンツが得られます。

[#<XML::Attribute:0x1287690 name="ID" value="bar">]

そして、インスタンスメソッドを持つものをnodeset.class返します。だから私は値を得るためにこれを行うことができるはずだと信じています: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]

メソッドが[]nodeset を Float64 としてinspect認識している理由がわかりません。classXML::Nodeset

私は何が欠けていますか?

[]String にはメソッドがあり、Float64 にはメソッドがないのは偶然ですか?

4

2 に答える 2

4

実行する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
于 2015-09-18T12:44:07.007 に答える
0

完全を期すために、@asterite と @waj の助けを借りて、最終的に完成したコードを次に示します。

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

node.value も間違っていることに注意してください。

于 2015-09-18T13:16:01.900 に答える