2014-10-07 53 views
0

我有一個XML文檔和XML節點,我想檢查這個文檔是否包含節點。例如,如何測試XML包含節點

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

我該如何實現這一點,並檢查忽略空格是首選。

在此先感謝

回答

1

你可以做

doc.descendant.contains(node) 

「後裔」創建所有的孩子的名單和遞歸。
這對於簡單的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. 的包含(節點)遍歷列表
+0

你能解釋爲什麼更多的是效率不高? – 2014-10-08 00:15:15

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。 因此,要小心並寫出更多測試。

相關問題