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)
について不平を言います。 
このような場合の私の秘密兵器は、tagsoup を使用することです。
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)
もう 1 つの方法は、標準のパーサーを使用して、次のような Doctype を追加することでした。
<!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()
""