1

注意: ここでは XPath 構文が死んでいると考えてください。

xml ノード (実際には HTML) があり、その属性を取得したいと考えています。

C# (HTMLAgilityPack) では、属性オブジェクトを名前で取得できました。たとえば、「a」ノードがあると、「href」属性を要求できます。

Scala では xml.Node 内に "attribute" メソッドがありますが、これは一連ノードを返します。属性はノードですか? 同じ名前の複数の属性をどのように持つことができますか? 私は完全に困惑しています。

さらに、xml.Attribute クラスがありますが、xml.Node で使用されているようには見えません。

私は PiS の本を持っていますが、XML の章は非常に浅いです。

質問

属性を要求してノードのコレクションを取得することをどのように理解すればよいですか?

IOW:属性を返すのではなく、ノードコレクションオプションを返すことにどのような意味がありますか?

  • オプション -- 属性がない場合、コレクションは空である必要があり、セマンティクスが 2 倍になります
  • コレクション -- これは、複数の属性が可能であることを意味するため、サイズ > 1 のコレクションを取得するシナリオに興味があります。
  • ノード - 属性は非常に単純なエンティティです。なぜそのようなやり過ぎであり、属性がツリー構造を持つことができるかを示唆しています
4

2 に答える 2

4

属性の値を取得したいだけですよね?その場合、それは非常に簡単です。

scala> val x = <foo this="xx" that="yy" />
x: scala.xml.Elem = <foo this="xx" that="yy"></foo>

scala> x.attribute("this")
res0: Option[Seq[scala.xml.Node]] = Some(xx)

scala> x.attribute("this").get.toString
res1: String = xx

XPath構文には明示的に興味がないとおっしゃっていたと思いますが、この場合は、実際にはかなりきれいです。

scala> x \ "@this"
res2: scala.xml.NodeSeq = xx

以上のことをすべて述べましたが、Scalaの組み込みXML処理での属性処理には多くの問題があることに注意する必要があります。たとえば、thisthisthisを参照してください。

于 2011-11-12T11:09:15.957 に答える
0

ポールのフォローアップの回答があなたの質問をほぼカバーしていることに気づきましたが、さらにいくつかの点を追加したいと思います。

  1. 私は個人的に Scala XML の設計が好きではなく、別のライブラリーScales Xmlを作成した程度ですが、設計が悪いとは言いません。その設計要素は、Anti-Xml のアプローチ (子を所有する要素、ノードをグループ化する概念など) の基礎を形成するのに十分なようですが、コンテナとしての属性とテキストが大きいという多くの癖があります。
  2. 私は最近、スケールに子孫軸をコミットしました-その貪欲な性質は、子孫または自己とは異なる動作をします-仕様によると、//para 1はロケーションパス/descendant::para 1と同じ意味ではありません
  3. Anti-Xml が存在しないか、若いプロジェクト (7 か月以上経ったか?) であり、子孫を追加することにまだ慣れていないため、不適切な設計を Anti-Xml に帰することができるかどうかはわかりません。

スケールの属性の質問に対する直接的な答えは次のとおりです。

val pre = Namespace("uri:test").prefixed("pre")

val elem = Elem("fred"l, emptyAttributes + 
        ("attr", "value") +
        Attribute(pre("attr"), "value"))

println("attributes are a map " + elem.attributes("attr"))

println("attributes are a set " + (
  elem.attributes + ("attr", "new value")))

val xpath = top(elem) \@ pre("attr")

xpath foreach{ap => println(ap.name)}

与える

[info] attributes are a map Some(Attribute({}attr,value))
[info] attributes are a set ListSet(Attribute({}attr,new value), Attribute({uri:test}attr,value))
[info] {uri:test}attr

XPath 構文は、一致する属性に到達した任意の数のパスである可能性があるため、コレクションを返す必要があります。要素属性自体は、名前空間がないことを意味する「attr」と一致する QName と attr の localName です。追加の健全性のために、属性 QName は次のとおりです。

type AttributeQName = EitherLike[PrefixedQName, NoNamespaceQName]

コンパイラーは、QName だけが入ってくるローカル名がないことを確認します。

余談ですが、Scala XML XPath のような構文がおそらく面白くない理由は理解できますが、Scales for XPath based querying を参照してください。

XPath 1.0 文字列ベースのクエリ (スナップショット以外のバージョンにはまだプッシュされていません) と、コンパイラ/ide を利用できる内部 DSL の両方があります (さらに、はるかに高速で、scala コードを直接操作できるというボーナスもあります)。

于 2011-11-13T12:08:48.867 に答える