Scala中的XML节点与属性?

时间:2011-11-12 10:22:21

标签: xml scala html xmlnode

备注:请在这里考虑XPath语法,谢谢。

我有xml节点(实际是HTML),我想得到它的一个属性。

在C#(HTMLAgilityPack)中,我可以按名称获取属性对象。例如,有一个“a”节点,我可以要求“href”属性。

在Scala中,xml.Node中有“attribute”方法,但这会返回节点序列。属性是一个节点?如何使用相同名称的多个属性?我完全不解。

此外还有xml.Attribute类,但我没有看到它在xml.Node中使用。

我有PiS书,但XML章节很浅。

问题

我应该如何理解要求获取节点集合的属性?

IOW:返回集合 节点选项而不是返回属性有什么意义?

  • 选项 - 如果没有属性,则集合应该为空,它是双倍语义
  • 集合 - 这意味着有多个属性可能,所以我很好奇在什么情况下我收集了大小> 1
  • node - 属性非常简单的实体,为什么这样的过度杀伤并建议该属性可以有树结构

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我意识到保罗的后续答案几乎涵盖了你的问题,但我想补充几点:

  1. 我个人不喜欢Scala XML的设计,只要我编写了一个替代库Scales Xml,但我不会称之为设计糟糕。它的设计元素显然也足以构成Anti-Xml方法的基础(元素拥有自己的孩子,分组节点的概念等),但有许多怪癖 - 属性和文本作为容器是一个大的。
  2. 我最近才向Scales提交了后代轴 - 它的贪婪性质与后代或自我的工作方式不同 - 根据规范// para 1并不意味着与位置路径/后代相同: :第1
  3. 我不确定你是否可以将不良设计归咎于Anti-Xml因为它的缺席,它是一个年轻的项目(刚刚超过七个月?)他们可能根本就没有完全添加后代。
  4. Scales的属性问题的直接答案是:

    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语法必须返回一个集合,因为它可以是到达匹配属性的任意数量的路径。元素属性本身是QName匹配的“attr”,意味着没有命名空间和attr的localName。为了额外的完整性,属性QName是:

    type AttributeQName = EitherLike[PrefixedQName, NoNamespaceQName]
    

    编译器确保没有本地名称只有QNames蠕变。

    顺便说一句,虽然我理解为什么Scala XML XPath语法可能没什么兴趣,但你应该看看基于XPath的Scales查询。

    有基于XPath 1.0字符串的查询(尚未推送到非快照版本)和内部dsl,它允许编译器/ ide帮助您(加上更快更好并直接使用scala代码的奖励)。