3

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このような場合の私の秘密兵器は、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&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()
""
4

1 に答える 1

2

構文解析を標準に準拠させるか、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 の両方から。したがって、期待どおりに動作した私にとっては、「ac:special」タグ内に「special」というテキストが表示されます。

DTD バリアントに関しては、キャッシング プロキシを介して DTD を解決したり、ローカル コピーを参照したり、DTD を必要最小限に減らしたりすることもできます。&nbsp;エンティティ全体を把握するには、次の情報で十分です。

<!DOCTYPE DOC[<!ENTITY nbsp "&#160;">]>
于 2013-08-18T10:09:01.410 に答える