3

次のようなxml(変数レポートに保存)があります。

<wrapper>
    <Sample Id="SomeId1">
        <Tag Id="SomeTag">
          <Lane Id="1">
           [...]
          </Lane>
        </Tag>
    </Sample>
    <Sample Id="SomeId2">
        <Tag Id="SomeTag">
          <Lane Id="1">
           [...]
          </Lane>
        </Tag>
    </Sample>
</wrapper>

「Sample」ノードから「Id」属性を抽出したい。次の記事http://www.codecommit.com/blog/scala/working-with-scalas-xml-supportを読んでから、次のことを試しました。

(report \\ "Sample" \ "@Id").text

戻り値として空の文字列を取得しました:

scala> (report \\ "Sample" \ "@Id").text
res16: String = ""

しかし、 return として "SomeId1SomeId2" が必要です。私は何を間違えましたか?

私に似た質問がいくつか見つかりました。例: Scala: XML 属性の解析

4

5 に答える 5

4

私はそれを次のように動作させました:

(xml \\ "Sample").map(n => (n \ "@Id").text)

=> scala.collection.immutable.Seq[String] = List(SomeId1, SomeId2)

しかし、もっと良い解決策 があるに違いありません…</p>

于 2012-08-01T12:41:46.563 に答える
2

セレクターを使用して複数の要素を持つ\属性を選択すると、ソースNodeSeqからわかるように、空の結果が得られます。

def \(that: String): NodeSeq = {
  ...
  that match {
    case "" => fail
    case "_" => makeSeq(!_.isAtom)
    case _ if (that(0) == '@' && this.length == 1) => atResult
    case _ => makeSeq(_.label == that)
  }
}

これについては以前に疑問に思っていましたが、正しく覚えていれば、これが文書化された動作であると判断できませんでした。現時点では、間違いなく文書を見つけることができません。

いずれにせよ、現在の実装はハックのように感じられ、奇妙な動作につながります。

scala> val bar = <bar>{ <baz/>.copy(label = "@baz") }</bar>
bar: scala.xml.Elem = <bar><@baz></@baz></bar>

scala> <foo>{ bar }</foo> \\ "bar" \ "@baz"
res0: scala.xml.NodeSeq = NodeSeq()

scala> <foo>{ bar ++ bar }</foo> \\ "bar" \ "@baz"
res1: scala.xml.NodeSeq = NodeSeq(<@baz></@baz>, <@baz></@baz>)

これはひどい例ですが、結果はまだかなり恐ろしいものです。

回避策として、属性のテキスト要素(report \\ "Sample").flatMap(_ \"@Id")を取得するようなものを個人的に作成し、必要に応じてその上にマップします。NodeSeqtext

于 2012-08-01T16:22:17.733 に答える
1

これをさらに実験して、@ Jean-Philippe Pelletが提供するものに代わる解決策を見つけました。これは、もう少し明確だと思います(これを行うにはさらに良い方法があると確信していても)。

report.\\("Sample").foreach(s => println(s.attribute("Id").get.text))

これはこれを返します:

scala> report.\\("Sample").foreach(s => println(s.attribute("Id").get.text))
SomeId1
SomeId2

\ メソッドは NodeSeq を返すため、各ノードを反復処理してその属性を取得し、それを使って何かを行うことができます。この場合、それらを取得して文字列に変換して出力するだけですが、これにより、より複雑な操作も可能になると思います。

于 2012-08-01T14:32:01.573 に答える
0

以下:

(report \ "Sample").head \ "@Id"

属性を含む NodeSeq になります。属性の入力には単一のノードが必要なようです (残念ながら、その仮定に関するドキュメントは見つかりませんでした - 参照リンクを歓迎します)

于 2012-08-01T15:07:11.843 に答える
-3

\ の代わりに [] を使用する必要があります

\\"Sample"[@Id]
于 2012-08-01T11:56:43.940 に答える