gpt4 book ai didi

groovy - 使用命名空间和实体在 Groovy 中解析 XML

转载 作者:行者123 更新时间:2023-12-02 02:35:19 27 4
gpt4 key购买 nike

在 Groovy 中解析 XML 应该是小菜一碟,但我总是遇到问题。

我想解析这样的字符串:

<html>
<p>
This&nbsp;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) ,解析器提示 &nbsp实体。在这种情况下,我的 secret 武器是使用 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&nbsp;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()
""

最佳答案

您必须决定是否希望解析符合标准、采用 DTD 路径,还是仅接受具有宽松解析器的任何内容。

根据我的经验,Tagsoup 适合后者,而且很少产生任何问题,所以我很惊讶地读到你关于它处理“特殊”的评论。快速测试还表明我无法重现它:运行此命令时

  java net.sf.saxon.Query -x:org.ccil.cowan.tagsoup.Parser -s:- -qs:. !encoding=ASCII !indent=yes

在您的样本上,我收到了这个结果

<?xml version="1.0" encoding="ASCII"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml">
<body>
<p>
This&#xa0;is a <span>test</span> with <b>some</b> formattings.<br clear="none"/>
And this has a <ac:special xmlns:ac="urn:x-prefix:ac">special</ac:special> formatting.
</p>

</body>
</html>

来自 TagSoup 1.2 和 1.2.1。因此,对我来说,其行为符合预期,文本“special”出现在“ac:special”标签内。

对于 DTD 变体,您可以通过缓存代理来解析 DTD,引用本地副本,甚至将 DTD 减少到您需要的最低限度。以下内容应该足以让您了解   实体:

<!DOCTYPE DOC[<!ENTITY nbsp "&#160;">]>

关于groovy - 使用命名空间和实体在 Groovy 中解析 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18297406/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com