Scala-如何提取通用文本文件中包含的XML文件

时间:2019-01-28 22:17:56

标签: xml scala

我有一个非常具体(而且很怪异)的文本文件,它不是XML文件,而是包含一个XML文档。它的结构或多或少是这样的:

Some text that I am not interested in...
More text that I don't need.

<tagIWant>
   <...>
   <!-- A large XML document -->
   <...>
</tagIwant>

Some more text...

我想在Scala中解析此文本文件,并从<tagIWant></tagIWant>提取XML文件。我知道XML解析器在Scala中非常强大,但是显然不能将其解析为XML。

3 个答案:

答案 0 :(得分:2)

MIGHT可行的一种方法(用Java术语,您必须转换为Scala)是从您自己的Reader向解析器提供输入,在SAX ContentHandler中使用解析器的输出,并返回-从ContentHandler到Reader的通道,以便在报告最外面的元素的endElement事件后,立即通知Reader停止提供输入。

之所以可能不起作用,是因为解析器可能会缓冲来自阅读器的输入,因此,当ContentHandler告诉阅读器停止时,为时已晚。

可惜的是,XML解析器没有一个选项可以在检测到结束符时停止没有错误的解析,但是如果有一个带有该选项的解析器,我没有遇到。您可以随时尝试修改开放源代码解析器!

答案 1 :(得分:1)

val text = """
Some text that I am not interested in...
More text that I don't need.

<tagIWant>
   <qqq>
   <!-- A large XML document -->
   </qqq>
</tagIWant>

Some more text...
"""

val pattern = "(?s).*(<tagIWant>.*</tagIWant>).*".r
val xml = pattern.findFirstMatchIn(text).map(m => m.group(1)).map(x => scala.xml.XML.loadString(x))

结果是Option[scala.xml.Elem]包含您的XML或无。

另外,请考虑使用pattern.findAllMatchIn

答案 2 :(得分:0)

最好先对文件进行预处理,以除去非XML位,然后再将其传递给XML解析器。这段代码将去除所有没有XML标记的开头和结尾行:

val isTag = "<[^>]+>".r
val xml =
  text.split("\n")
    .dropWhile(isTag.findFirstMatchIn(_).isEmpty)
    .reverse
    .dropWhile(isTag.findFirstMatchIn(_).isEmpty)
    .reverse
    .mkString("\n")

您可以将text.split("\n")替换为将文本文件读取为String值列表的任何代码。

这假定开头标记是一行中的第一个文本,而结束标记是一行中的最后一个文本。