Mercurial Hosting > luan
changeset 1791:f8f5c51f5b36
xml work
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 26 Dec 2023 19:16:18 -0700 |
parents | a8c685a894b4 |
children | a5f62fe28b3e |
files | src/goodjava/xml/XmlElement.java src/luan/modules/Parsers.luan src/luan/modules/Xml.luan src/luan/modules/parsers/LuanToString.java src/luan/modules/parsers/Xml2.java |
diffstat | 5 files changed, 109 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/src/goodjava/xml/XmlElement.java Mon Dec 25 23:07:59 2023 -0700 +++ b/src/goodjava/xml/XmlElement.java Tue Dec 26 19:16:18 2023 -0700 @@ -7,6 +7,7 @@ public final String name; public final Map<String,String> attributes; private Object content = null; + private XmlElement parent = null; public XmlElement(String name,Map<String,String> attributes) { this.name = name; @@ -14,6 +15,10 @@ this.content = null; } + public XmlElement getParent() { + return parent; + } + public Object getContent() { return content; } @@ -34,6 +39,9 @@ if( content.length == 0 ) throw new IllegalArgumentException("content can't be empty"); this.content = content; + for( XmlElement el : content ) { + el.parent = this; + } } @Override public String toString() {
--- a/src/luan/modules/Parsers.luan Mon Dec 25 23:07:59 2023 -0700 +++ b/src/luan/modules/Parsers.luan Tue Dec 26 19:16:18 2023 -0700 @@ -4,6 +4,7 @@ local Csv = require "java:luan.modules.parsers.Csv" local Theme = require "java:luan.modules.parsers.Theme" local Xml = require "java:luan.modules.parsers.Xml" +local Xml2 = require "java:luan.modules.parsers.Xml2" local XmlElement = require "java:goodjava.xml.XmlElement" local BasicLuan = require "java:luan.modules.BasicLuan" @@ -18,6 +19,8 @@ Parsers.xml_encode = XmlElement.encode Parsers.xml_parse = Xml.parse Parsers.xml_string = Xml.toString +Parsers.xml2_parse = Xml2.parse +Parsers.xml2_string = Xml2.toString local Luan = require "luan:Luan.luan" local error = Luan.error
--- a/src/luan/modules/Xml.luan Mon Dec 25 23:07:59 2023 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -require "java" -local XmlParser = require "java:goodjava.xml.XmlParser" -local XmlElement = require "java:goodjava.xml.XmlElement" -local Luan = require "luan:Luan.luan" -local error = Luan.error -local set_metatable = Luan.set_metatable or error() - - -local Xml = {} - -Xml.encode = XmlElement.encode - -local function new(java,mt) - local t = {} - t.java = java - set_metatable(t,mt) - return t -end - -local element_mt = {} - -local xml_mt = {} -function xml_mt.__index(xml,key) - if key == "element" then - return new( xml.java.element, element_mt ) - end - if key == "declaration" then - return xml.java.declaration - end - return nil -end -function xml_mt.__new_index(xml,key,value) - if key == "element" then - xml.java.setElement( value.java ) - elseif key == "declaration" then - xml.java.declaration = value - else - error("invalid key: "..key) - end -end -function xml_mt.__to_string(xml) - return xml.java.toString() -end - -function Xml.parse(text) - return new( XmlParser.parse(text), xml_mt ) -end - -return Xml
--- a/src/luan/modules/parsers/LuanToString.java Mon Dec 25 23:07:59 2023 -0700 +++ b/src/luan/modules/parsers/LuanToString.java Tue Dec 26 19:16:18 2023 -0700 @@ -79,6 +79,7 @@ private final Luan luan; private final LuanFunction fnOptions; private final LuanTable stack = new LuanTable(); + private final Set<LuanTable> seen = new HashSet<LuanTable>(); public LuanToString() { this.luan = null; @@ -115,11 +116,11 @@ public String toString(Object obj) throws LuanException { StringBuilder sb = new StringBuilder(); - toString(obj,sb,0,settingsInit); + objectToString(obj,sb,0,settingsInit); return sb.toString(); } - private void toString(Object obj,StringBuilder sb,int indented,Settings settings) throws LuanException { + private void objectToString(Object obj,StringBuilder sb,int indented,Settings settings) throws LuanException { if( obj == null ) { sb.append( "nil" ); return; @@ -148,6 +149,12 @@ } private void toString(LuanTable tbl,StringBuilder sb,int indented,Settings settings) throws LuanException { + if( !seen.add(tbl) ) { + if( settings.strict ) + throw new LuanException("loop in "+tbl.rawToString()); + sb.append("<loop>"); + return; + } if( tbl.getMetatable()!=null ) { if( settings.strict ) throw new LuanException("can't handle metatables when strict"); @@ -207,7 +214,7 @@ } else { indent(sb,indented+1); } - toString(obj,sb,indented+1,settings); + objectToString(obj,sb,indented+1,settings); } for( Object obj : map.entrySet() ) { Map.Entry entry = (Map.Entry)obj; @@ -247,7 +254,7 @@ sb.append( (String)key ); } else { sb.append( '[' ); - toString( key, sb, indented, keySettings ); + objectToString( key, sb, indented, keySettings ); sb.append( ']' ); } sb.append( settings.compressed ? "=" : " = " ); @@ -257,7 +264,7 @@ settings = settings.cloneSettings(); settings.applyOptions(options); } - toString( entry.getValue(), sb, indented, settings ); + objectToString( entry.getValue(), sb, indented, settings ); stack.removeFromList(stack.rawLength()); // pop }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/parsers/Xml2.java Tue Dec 26 19:16:18 2023 -0700 @@ -0,0 +1,86 @@ +package luan.modules.parsers; + +import java.util.Map; +import java.util.LinkedHashMap; +import goodjava.parser.ParseException; +import goodjava.xml.XmlParser; +import goodjava.xml.Xml; +import goodjava.xml.XmlElement; +import luan.LuanTable; +import luan.LuanException; + + +public final class Xml2 { + + public static LuanTable parse(String s) throws ParseException, LuanException { + Xml xml = XmlParser.parse(s); + LuanTable tbl = new LuanTable(); + tbl.rawPut( "declaration", xml.declaration ); + tbl.rawPut( "element", newElement(xml.getElement()) ); + return tbl; + } + + private static LuanTable newElement(XmlElement element) throws LuanException { + LuanTable tbl = new LuanTable(); + tbl.rawPut( "name", element.name ); + LuanTable attrs = new LuanTable(); + for( Map.Entry<String,String> entry : element.attributes.entrySet() ) { + attrs.rawPut(entry.getKey(),entry.getValue()); + } + tbl.rawPut( "attributes", attrs ); + Object content = element.getContent(); + if( content == null ) { + // nothing + } else if( content instanceof String ) { + tbl.rawPut( "content", content ); + } else { + XmlElement[] elements = (XmlElement[])content; + LuanTable t = new LuanTable(); + for( XmlElement el : elements ) { + LuanTable elTbl = newElement(el); + elTbl.rawPut( "parent", tbl ); + t.rawAdd(elTbl); + } + tbl.rawPut( "content", t ); + } + return tbl; + } + + + public static String toString(LuanTable tbl) { + Xml xml = new Xml(); + xml.declaration = (String)tbl.rawGet("declaration"); + xml.setElement( element( (LuanTable)tbl.rawGet("element") ) ); + return xml.toString(); + } + + private static XmlElement element(LuanTable tbl) { + String name = (String)tbl.rawGet("name"); + Map<String,String> map = new LinkedHashMap<String,String>(); + { + LuanTable t = (LuanTable)tbl.rawGet("attributes"); + for( Map.Entry entry : t.rawIterable() ) { + String key =(String)entry.getKey(); + String value =(String)entry.getValue(); + map.put(key,value); + } + } + XmlElement element = new XmlElement(name,map); + Object content = tbl.rawGet("content"); + if( content == null ) { + // nothing + } else if( content instanceof String ) { + element.setContent((String)content); + } else if( content instanceof LuanTable ) { + LuanTable t = (LuanTable)content; + int n = t.rawLength(); + XmlElement[] a = new XmlElement[n]; + for( int i=0; i<n; i++ ) { + LuanTable elTbl = (LuanTable)t.rawGet(Integer.valueOf(i+1)); + a[i] = element(elTbl); + } + element.setContent(a); + } + return element; + } +}