Xiaohe Dong
Xiaohe Dong

Reputation: 5023

How to test XML contain node

I have a xml doc and xml node, I want to check this doc contain node or not. for example,

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

How should I implement this and check ignoring white space is preferred.

Thanks in advance

Upvotes: 0

Views: 576

Answers (2)

roterl
roterl

Reputation: 1883

You can do

doc.descendant.contains(node)

'descendant' create list of all the childs and recursively.
This should be enough for simple xmls, but it isn't efficient way because it it create a list that contains all the nodes, and their sub-nodes recursively.

If you run

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)

which is not bad, but when using larger 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)

As you can see the list is become larger. so you pay twice:

  1. generate the list meaning traverse the entire xml
  2. the contains(node) traverse the list

Upvotes: 1

hellraiser
hellraiser

Reputation: 1451

Perhaps this can help.

Comparison operations over XML data, actually, are the comparison operations over AST data represented in XML format. So you can use any library works with AST data and supports import from XML. I prefer json and json4s.org library.

So, you can goal your aim with the following way:

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

But you should know, that XML has troubles with AST transformations because of its node attributes. Example issue. Thus, be careful and write more tests.

Upvotes: 0

Related Questions