Mercurial Hosting > luan
view src/luan/modules/parsers/Xml.java @ 1802:ca98dee04e08 default tip
add Parsers.json_null
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 21 Apr 2024 21:25:15 -0600 |
parents | a8c685a894b4 |
children |
line wrap: on
line source
package luan.modules.parsers; import java.util.Collections; import java.util.Map; import java.util.LinkedHashMap; import java.util.List; import java.util.ArrayList; import goodjava.parser.ParseException; import goodjava.xml.XmlElement; import goodjava.xml.XmlParser; import luan.Luan; import luan.LuanTable; import luan.LuanException; import luan.modules.BasicLuan; public final class Xml { public static String toString(LuanTable tbl) throws LuanException { XmlElement[] elements = elements(tbl); if( elements.length != 1 ) throw new LuanException("XML must have 1 root element"); return elements[0].toString(); } private static final String ATTRIBUTES = "xml_attributes"; private static final String TEXT = "xml_text"; private static XmlElement[] elements(LuanTable tbl) throws LuanException { List<XmlElement> list = new ArrayList<XmlElement>(); for( Map.Entry entry : tbl.rawIterable() ) { Object key = entry.getKey(); if( !(key instanceof String) ) throw new LuanException("XML key must be string"); String name = (String)key; Object value = entry.getValue(); if( name.equals(ATTRIBUTES) ) continue; if( name.equals(TEXT) ) throw new LuanException("Can't mix text and elements"); LuanTable t = (LuanTable)value; if( t.isMap() ) { list.add( element(name,t) ); } else { for( Object obj : t.asList() ) { list.add( element(name,obj) ); } } } return list.toArray(new XmlElement[0]); } private static XmlElement element(String name,Object obj) throws LuanException { if( obj instanceof String ) { XmlElement element = new XmlElement( name, Collections.emptyMap() ); element.setContent( (String)obj ); return element; } LuanTable t = (LuanTable)obj; Map<String,String> attributes = attributes(t); String s = (String)t.rawGet(TEXT); if( s != null ) { XmlElement element = new XmlElement(name,attributes); element.setContent(s); return element; } else { XmlElement[] elements = elements(t); if( elements.length==0 ) { return new XmlElement(name,attributes); } else { XmlElement element = new XmlElement(name,attributes); element.setContent(elements); return element; } } } private static Map<String,String> attributes(LuanTable tbl) throws LuanException { Object obj = tbl.rawGet(ATTRIBUTES); if( obj==null ) return Collections.emptyMap(); LuanTable t = (LuanTable)obj; Map<String,String> map = new LinkedHashMap<String,String>(); for( Map.Entry entry : t.rawIterable() ) { String name =(String)entry.getKey(); String value =(String)entry.getValue(); map.put(name,value); } return map; } public static LuanTable parse(String s) throws ParseException, LuanException { XmlElement element = XmlParser.parse(s).getElement(); LuanTable tbl = new LuanTable(); addElements(tbl,new XmlElement[]{element}); return tbl; } private static LuanTable addElements(LuanTable tbl,XmlElement[] elements) throws LuanException { for( XmlElement element : elements ) { LuanTable t = new LuanTable(); if( !element.attributes.isEmpty() ) { LuanTable attrs = new LuanTable(); for( Map.Entry<String,String> entry : element.attributes.entrySet() ) { attrs.rawPut(entry.getKey(),entry.getValue()); } t.rawPut( ATTRIBUTES, attrs ); } Object content = element.getContent(); if( content == null ) { // nothing } else if( content instanceof String ) { t.rawPut( TEXT, content ); } else { XmlElement[] els = (XmlElement[])content; addElements(t,els); } LuanTable old = (LuanTable)tbl.rawGet(element.name); if( old==null ) { tbl.rawPut(element.name,t); } else { if( !old.isList() ) { LuanTable list = new LuanTable(); list.rawAdd(old); old = list; tbl.rawPut(element.name,old); } old.rawAdd(t); } } return tbl; } }