Created
September 17, 2011 01:00
-
-
Save fumokmm/1223474 to your computer and use it in GitHub Desktop.
Make Groovy's MarkupBuilder style DSL String
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://d.hatena.ne.jp/fumokmm/20110917/1316223642 | |
import org.xml.sax.helpers.DefaultHandler | |
import org.xml.sax.Attributes | |
class GroovyMarkupDSLHandler extends DefaultHandler { | |
IndentPrinter p | |
boolean needNewLine | |
GroovyMarkupDSLHandler(Writer writer = new PrintWriter(System.out), String indent = ' ') { | |
p = new IndentPrinter(writer, indent) | |
needNewLine = false | |
} | |
def toAttrMap = { Attributes attr -> | |
attr.length ? (0..<attr.length).collectEntries{ | |
[attr.getQName(it), attr.getValue(it)] | |
} : null | |
} | |
def toMethodCall = { Map attrMap -> | |
attrMap.collect{ "${it.key}: '${it.value}'" }.join(', ') | |
} | |
def printNewLineIfNeed() {if (needNewLine) {p.println ''; needNewLine = false}} | |
@Override void startDocument() { | |
//println "GroovyMarkupDSLHandler START." | |
} | |
@Override void endDocument() { | |
p.flush() | |
//println "GroovyMarkupDSLHandler END." | |
} | |
@Override void startElement(String ns, String localName, String qName, Attributes atts) { | |
printNewLineIfNeed() | |
p.printIndent() | |
def attr = toAttrMap(atts) | |
if (attr) { | |
p.println "$qName(${toMethodCall(attr)}) {" | |
} else { | |
p.println "$qName {" | |
} | |
p.incrementIndent() | |
} | |
@Override void endElement(String ns, String localName, String qName) { | |
printNewLineIfNeed() | |
p.decrementIndent() | |
p.printIndent() | |
p.print '}' | |
needNewLine = true | |
} | |
@Override void characters(char[] chars, int offset, int length) { | |
printNewLineIfNeed() | |
def str = chars[offset..<offset+length].join().trim() | |
if(str) { | |
p.printIndent() | |
p.println "mkp.yield('${str}')" | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.xml.parsers.SAXParserFactory | |
import org.xml.sax.helpers.DefaultHandler | |
import org.xml.sax.InputSource | |
import groovy.xml.MarkupBuilder | |
def getDSLString(File xml, Writer w, String indent = ' ') { | |
def handler = new GroovyMarkupDSLHandler(w, indent) | |
def reader = SAXParserFactory.newInstance().newSAXParser().xmlReader | |
reader.contentHandler = handler | |
reader.parse(new InputSource(xml.newInputStream())) | |
} | |
def s1 = new StringWriter() | |
getDSLString(new File('test1.xml'), s1) | |
def expected1 = '''\ | |
root { | |
a { | |
b { | |
c { | |
} | |
} | |
} | |
}''' | |
assert expected1 == s1.toString() | |
// 逆変換(一旦DSLにしたものをMarkupした結果のXMLと元のXMLを比較) | |
assert new File('test1.xml').text == Eval.me(""" | |
def sw = new StringWriter() | |
def xml = new groovy.xml.MarkupBuilder(sw) | |
xml.doubleQuotes = true | |
xml.${s1.toString()} | |
sw.toString() | |
""") | |
def s2 = new StringWriter() | |
getDSLString(new File('test2.xml'), s2, ' '*4) // タブ=スペース*4 | |
def expected2 = '''\ | |
root { | |
a(hoge: 'val1', fuga: 'val2') { | |
} | |
b { | |
} | |
c(hoge: 'val3') { | |
d { | |
mkp.yield('val4') | |
} | |
e { | |
f(hoge: 'val5') { | |
mkp.yield('ばりゅー6') | |
} | |
} | |
} | |
}''' | |
assert expected2 == s2.toString() | |
// 逆変換(一旦DSLにしたものをMarkupした結果のXMLと元のXMLを比較) | |
assert new File('test2.xml').text == Eval.me(""" | |
def sw = new StringWriter() | |
def xml = new groovy.xml.MarkupBuilder(sw) | |
xml.doubleQuotes = true | |
xml.${s2.toString()} | |
sw.toString() | |
""") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<root> | |
<a> | |
<b> | |
<c /> | |
</b> | |
</a> | |
</root> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<root> | |
<a hoge="val1" fuga="val2" /> | |
<b /> | |
<c hoge="val3"> | |
<d>val4</d> | |
<e> | |
<f hoge="val5">ばりゅー6</f> | |
</e> | |
</c> | |
</root> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment