倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

ビルダーの本末転倒な使い方 Revolution

前にやった「ビルダーの本末転倒な使い方」、「ビルダーの本末転倒な使い方 Reloaded」って、よく考えたら、「ビルダーをイベントハンドラと思えば単なる Push 解析」ですねぇ。

ってことで、サンプルコードをちょっと SAXParser 風にしてみると

class PushParser{

    def parseText(String xml, builder){
        parse(new StringReader(xml), builder)
    }

    def parse(Reader reader, builder){
        def parser = new XmlParser()
        def xml = parser.parse(reader)
        buildNode(xml, builder)
    }

    def buildNode(node, builder){
        def secondArg = (node.text()) ? node.text() : createContentClosure(node, builder)
        builder.invokeMethod(node.name(), [node.attributes(), secondArg])
    }

    private createContentClosure(node, builder){
        return {
            for(child in node.children()){
                buildNode(child, builder)
            }
        }
    }
}

といった感じになります。

このクラスを使用するコードはこんな感じ:

def xml = '''<table customer='c' invoice='i'>
  <join c='invoice_id' i='id' />
  <and>
    <greater i.total='1000' />
    <like c.name='%Bill%' >description</like>
  </and>
</table>'''

def parser = new PushParser()
def builder = new groovy.xml.MarkupBuilder()
parser.parseText(xml, builder)

ビルダーをインスタンスに持つ org.xml.sax.ContentHandler のサブクラスを作れば SAX 解析ともっと親和的になると思うけど、そこまでするほどのものでもないですね。

入門XML

入門XML


XMLマスター教科書 プロフェッショナル(データベース)

XMLマスター教科書 プロフェッショナル(データベース)