使用名称空间和实体在Groovy中解析XML



在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实体。在这种情况下,我的秘密武器是使用标签:

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:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

这似乎适用于我的大多数文件,但解析器获取并处理dtd需要很长时间

有什么好办法解决这个问题吗?

附言:这是一些可以玩的示例代码:

@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路径,或者只接受任何具有许可性的解析器。

根据我的经验,Tag汤对后者来说很好,它很少会产生任何问题,所以我很惊讶地读到你关于它处理"特殊"的评论。一个快速测试也表明我无法复制它:当运行这个命令时

  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减少到所需的最低限度。以下内容应足以让您了解&nbsp;实体:

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

相关内容

  • 没有找到相关文章

最新更新