在 Groovy 中解析 XML 应该是小菜一碟,但我总是遇到问题。
我想解析这样的字符串:
<html>
<p>
This is a <span>test</span> with <b>some</b> formattings.<br />
And this has a <ac:special>special</ac:special> formatting.
</p>
</html>
当我以标准方式执行此操作时new XmlSlurper().parseText(body)
,解析器会抱怨该 
实体。在这种情况下,我的秘密武器是使用 tagoup:
def parser = new org.ccil.cowan.tagsoup.Parser()
def page = new XmlSlurper(parser).parseText(body)
但是现在这个<ac:sepcial>
标签会被解析器立即关闭——special
文本不会在生成的 dom 中的这个标签内。即使我禁用了命名空间功能:
def parser = new org.ccil.cowan.tagsoup.Parser()
parser.setFeature(parser.namespacesFeature,false)
def page = new XmlSlurper(parser).parseText(body)
另一种方法是使用标准解析器并添加一个像这样的文档类型:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
这似乎适用于我的大多数文件,但解析器需要很长时间才能获取 dtd 并对其进行处理。
任何好主意如何解决这个问题?
PS:这里有一些示例代码可以玩:
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
def processNode(node) {
def out = new StringBuilder("")
node.children.each {
if (it instanceof String) {
out << it
} else {
out << "<${it.name()}>${processNode(it)}</${it.name()}>"
}
}
return out.toString()
}
def body = """<html>
<p>
This is a <span>test</span> with <b>some</b> formattings.<br />
And this has a <ac:special>special</ac:special> formatting.
</p>
</html>"""
def parser = new org.ccil.cowan.tagsoup.Parser()
parser.setFeature(parser.namespacesFeature,false)
def page = new XmlSlurper(parser).parseText(body)
def out = new StringBuilder("")
page.childNodes().each {
out << processNode(it)
}
println out.toString()
""