我有以下XML:
<data>
<a>...</a>
<b1>...</b1>
<c>...</c>
<b2>...</b2>
<d>...</d>
<b3>...</b2>
</data>
在Scala中,如何从data
节点(即Elem
对象)中提取以字符串“b”开头的节点?在这种情况下,所需的值是三个节点的序列:
[<b1>...</b1>, <b2>...</b2>, <b3>...</b3]
我试过这个,但它没有编译:
val orderNodes: NodeSeq = /data/*[starts-with(name(), "b")]
答案 0 :(得分:1)
小文档最简单的解决方案是使用您需要的谓词过滤节点序列:
val data = <data>
<a>...</a>
<b1>...</b1>
<c>...</c>
<b2>...</b2>
<d>...</d>
<b3>...</b3>
</data>
scala> (data \ "_").filter(_.label.startsWith("b"))
res1: scala.xml.NodeSeq = NodeSeq(<b1>...</b1>, <b2>...</b2>, <b3>...</b3>)
elem \ label
语法返回一系列节点,其名称完全等于label
。 elem \ "_"
是该语法的特例,它返回所有子元素。然后,您可以使用与任何普通Scala集合一样的节点序列。
答案 1 :(得分:0)
您可以使用scala.xml.XML.EventReader,它按标记读取XML文件标记。
有3个案例是starTag,text和endTag,你可以从XML文件中提取你想要的数据。
e.g。 //scala.io.Source
val source = new Source(“path to XML file”)
val eventReader=new EventReader(source)
parse(xml)
def parse ={
var isStartTag= false
var isEndTag = false
var list = mutable.List()
loop(currentNode) // tail recursive function
If(xml.hasNext){
xml.next match{
case startEvent(_,label,_,_) => //your logic
loop(currentNode)
case Text(text)=> // your logic
loop(currentNode )
case EndEvent => // your logic
loop(currentNode.tail)
case _ => loop(currentNode.tail)}}
loop(Nil)}
这样的东西可能会有一些合成错误。但想法是阅读您感兴趣的标签并进行处理。
它还可以帮助您实现真正的猪油文件,因为您只会将感兴趣的标签加载到内存中。
如果您有Elem对象,那么您可以这样做。 从Elem对象获取nodeSeq,并执行此操作。
node \\“your parent tag”\\“your child tag”
在您孩子和父母标签的位置,您可以提供正则表达式。
与节点\\“abc *”\\“b *”
类似如果您确定孩子在场,您可以使用。
node \\“您的父标记”\“您的子标记”