如何测试XML包含节点

时间:2014-10-07 00:51:47

标签: xml scala

我有一个xml doc和xml节点,我想检查这个doc是否包含节点。例如,

<foo><bar>123</bar></foo>, <bar>123</bar> true
<foo><bar>123</bar></foo> <bar></bar> false

def check(xmlDoc: String, xmlNode: String): Unit = {
    val doc = XML.loadString(xmlDoc)
    val node = XML.loadString(xmlNode)

    assert(???, "XML doc does not contain this node")
}

我应该如何实现这一点并检查忽略空格是首选。

提前致谢

2 个答案:

答案 0 :(得分:1)

你可以做到

doc.descendant.contains(node)

&#39;后代&#39;创建所有孩子的列表并递归 对于简单的xmls来说这应该足够了,但它不是有效的方式,因为它创建了一个包含所有节点及其子节点递归的列表。

如果你跑

scala> val doc = <foo><bar>123</bar></foo>
doc: scala.xml.Elem = <foo><bar>123</bar></foo>

scala> doc.descendant
res7: List[scala.xml.Node] = List(<bar>123</bar>, 123)

这不错,但使用更大的xml:

scala> val doc = <foo><doo><bar>123</bar></doo><bla>111</bla></foo>
doc: scala.xml.Elem = <foo><doo><bar>123</bar></doo><bla>111</bla></foo>

scala> doc.descendant
res10: List[scala.xml.Node] = List(<doo><bar>123</bar></doo>, <bar>123</bar>, 123, <bla>111</bla>, 111)

如您所见,列表变得更大。所以你付了两次钱:

  1. 生成列表意思遍历整个xml
  2. contains(node)遍历列表

答案 1 :(得分:0)

也许这会有所帮助。

实际上,对XML数据的比较操作是以XML格式表示的AST数据的比较操作。因此,您可以使用任何库与AST数据一起使用,并支持从XML导入。我更喜欢json和json4s.org库。

因此,您可以通过以下方式实现目标:

import org.json4s.Xml.toJson
import scala.xml.XML

val str1 = "<foo><bar>123</bar></foo>"
val str2 = "<bar>123</bar>"
val str3 = "<bar></bar>"

def check(xmlDoc: String, xmlNode: String) = {
  val docJs = toJson(XML.loadString(xmlDoc))
  val nodeJs = toJson(XML.loadString(xmlNode))

  assert(docJs.find(_.equals(nodeJs)).isDefined, "Description")
}

check(str1, str2) 
check(str1, str3) //java.lang.AssertionError: assertion failed: Description

但是您应该知道,由于其节点属性,XML在AST转换方面存在问题。示例issue。 因此,要小心并编写更多测试。