Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中查找名称中带有通配符的XML节点_Xml_Scala_Xpath - Fatal编程技术网

在Scala中查找名称中带有通配符的XML节点

在Scala中查找名称中带有通配符的XML节点,xml,scala,xpath,Xml,Scala,Xpath,我有以下XML: <data> <a>...</a> <b1>...</b1> <c>...</c> <b2>...</b2> <d>...</d> <b3>...</b2> </data> 我尝试过这个,但它无法编译: val orderNodes: NodeSeq = /dat

我有以下XML:

<data>
    <a>...</a>
    <b1>...</b1>
    <c>...</c>
    <b2>...</b2>
    <d>...</d>
    <b3>...</b2>
</data>
我尝试过这个,但它无法编译:

val orderNodes: NodeSeq = /data/*[starts-with(name(), "b")]

您可以使用scala.xml.xml.EventReader,它逐标记读取xml文件

它有三种情况,即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对象中获取nodeSeq并执行以下操作

节点\\“您的父标记”\\“您的子标记”

在您的孩子和家长标签的位置,您可以给出正则表达式

像节点\\“abc*”\\“b*”

如果您确信孩子会在场,您可以使用


节点\\“您的父标记”\“您的子标记”

对于小型文档,最简单的解决方案是使用您需要的谓词过滤节点序列:

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>)
val数据=
...
...
...
...
...
...
scala>(数据\“\”.filter(\.label.startsWith(“b”))
res1:scala.xml.NodeSeq=NodeSeq(…,…,…)

elem\label
语法返回一个节点序列,其名称与
label
完全相同。而
elem\“
是该语法的一个特例,它返回所有子元素。然后,您可以像处理任何普通Scala集合一样处理该节点序列。

我真的必须使用pull吗?我希望会有某种XPath解决方案。实际上,您应该使用pull,它可以让您确信获取感兴趣的数据。如果它是基于推送的,你将得到你想要的所有数据,而你不想要。所以我认为如果你的xml是gbs或者@paulreiners格式的话,pull会更好。也有一个路径解决方案,但它可以与xml元素一起使用,你可以使用xPath进行搜索,但是如果你这样做,你必须将整个xml加载到内存中,所以如果你的文件像是小容量的,你可以使用路径解决方案,我认为你可以研究这个问题。
data
前面的单斜杠表示
data
是根节点。否则它应该是双斜杠
//数据…
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>)