comparison src/luan/modules/parsers/Xml.java @ 1495:2e8a5df45d56

better xml
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 05 May 2020 11:03:48 -0600
parents f5b8c7e1ac82
children b89212fd04b5
comparison
equal deleted inserted replaced
1494:91c167099462 1495:2e8a5df45d56
9 import goodjava.xml.XmlElement; 9 import goodjava.xml.XmlElement;
10 import goodjava.xml.XmlParser; 10 import goodjava.xml.XmlParser;
11 import luan.Luan; 11 import luan.Luan;
12 import luan.LuanTable; 12 import luan.LuanTable;
13 import luan.LuanException; 13 import luan.LuanException;
14 import luan.modules.BasicLuan;
14 15
15 16
16 public final class Xml { 17 public final class Xml {
17 18
18 public static String toString(LuanTable tbl) throws LuanException { 19 public static String toString(LuanTable tbl) throws LuanException {
20 if( elements.length != 1 ) 21 if( elements.length != 1 )
21 throw new LuanException("XML must have 1 root element"); 22 throw new LuanException("XML must have 1 root element");
22 return elements[0].toString(); 23 return elements[0].toString();
23 } 24 }
24 25
25 private static final Integer ONE = Integer.valueOf(1); 26 private static final String ATTRIBUTES = "xml_attributes";
26 private static final Integer TWO = Integer.valueOf(2); 27 private static final String TEXT = "xml_text";
27 private static final String LIST = "$list";
28 28
29 private static XmlElement[] elements(LuanTable tbl) throws LuanException { 29 private static XmlElement[] elements(LuanTable tbl) throws LuanException {
30 List<XmlElement> list = new ArrayList<XmlElement>(); 30 List<XmlElement> list = new ArrayList<XmlElement>();
31 for( Map.Entry entry : tbl.iterable() ) { 31 for( Map.Entry entry : tbl.iterable() ) {
32 Object key = entry.getKey(); 32 Object key = entry.getKey();
33 if( key.equals(ONE) )
34 continue;
35 if( !(key instanceof String) ) 33 if( !(key instanceof String) )
36 throw new LuanException("XML key must be string"); 34 throw new LuanException("XML key must be string");
37 String name = (String)key; 35 String name = (String)key;
38 Object value = entry.getValue(); 36 Object value = entry.getValue();
39 if( value instanceof String ) { 37 if( name.equals(ATTRIBUTES) )
40 list.add( element(name,value) ); 38 continue;
39 if( name.equals(TEXT) )
40 throw new LuanException("Can't mix text and elements");
41 LuanTable t = (LuanTable)value;
42 if( t.isMap() ) {
43 list.add( element(name,t) );
41 } else { 44 } else {
42 LuanTable t = (LuanTable)value; 45 for( Object obj : t.asList() ) {
43 LuanTable tList = (LuanTable)t.get(LIST); 46 list.add( element(name,obj) );
44 if( tList == null ) {
45 list.add( element(name,t) );
46 } else {
47 for( Object obj : tList.asList() ) {
48 list.add( element(name,obj) );
49 }
50 } 47 }
51 } 48 }
52 } 49 }
53 return list.toArray(new XmlElement[0]); 50 return list.toArray(new XmlElement[0]);
54 } 51 }
57 if( obj instanceof String ) { 54 if( obj instanceof String ) {
58 return new XmlElement( name, Collections.emptyMap(), (String)obj ); 55 return new XmlElement( name, Collections.emptyMap(), (String)obj );
59 } 56 }
60 LuanTable t = (LuanTable)obj; 57 LuanTable t = (LuanTable)obj;
61 Map<String,String> attributes = attributes(t); 58 Map<String,String> attributes = attributes(t);
62 String s = (String)t.get(TWO); 59 String s = (String)t.get(TEXT);
63 if( s != null ) { 60 if( s != null ) {
64 return new XmlElement(name,attributes,s); 61 return new XmlElement(name,attributes,s);
65 } else { 62 } else {
66 XmlElement[] elements = elements(t); 63 XmlElement[] elements = elements(t);
67 if( elements.length==0 ) { 64 if( elements.length==0 ) {
71 } 68 }
72 } 69 }
73 } 70 }
74 71
75 private static Map<String,String> attributes(LuanTable tbl) throws LuanException { 72 private static Map<String,String> attributes(LuanTable tbl) throws LuanException {
76 Object obj = tbl.get(ONE); 73 Object obj = tbl.get(ATTRIBUTES);
77 if( obj==null ) 74 if( obj==null )
78 return Collections.emptyMap(); 75 return Collections.emptyMap();
79 LuanTable t = (LuanTable)obj; 76 LuanTable t = (LuanTable)obj;
80 Map<String,String> map = new LinkedHashMap<String,String>(); 77 Map<String,String> map = new LinkedHashMap<String,String>();
81 for( Map.Entry entry : t.iterable() ) { 78 for( Map.Entry entry : t.iterable() ) {
100 if( !element.attributes.isEmpty() ) { 97 if( !element.attributes.isEmpty() ) {
101 LuanTable attrs = new LuanTable(tbl.luan()); 98 LuanTable attrs = new LuanTable(tbl.luan());
102 for( Map.Entry<String,String> entry : element.attributes.entrySet() ) { 99 for( Map.Entry<String,String> entry : element.attributes.entrySet() ) {
103 attrs.put(entry.getKey(),entry.getValue()); 100 attrs.put(entry.getKey(),entry.getValue());
104 } 101 }
105 t.put( 1, attrs ); 102 t.put( ATTRIBUTES, attrs );
106 } 103 }
107 Object value = t;
108 if( element.content == null ) { 104 if( element.content == null ) {
109 // nothing 105 // nothing
110 } else if( element.content instanceof String ) { 106 } else if( element.content instanceof String ) {
111 if( t.isEmpty() ) { 107 t.put( TEXT, element.content );
112 value = element.content;
113 } else {
114 t.put( 2, element.content );
115 }
116 } else { 108 } else {
117 XmlElement[] els = (XmlElement[])element.content; 109 XmlElement[] els = (XmlElement[])element.content;
118 addElements(t,els); 110 addElements(t,els);
119 } 111 }
120 Object old = tbl.get(element.name); 112 LuanTable old = (LuanTable)tbl.get(element.name);
121 if( old==null ) { 113 if( old==null ) {
122 tbl.put(element.name,value); 114 tbl.put(element.name,t);
123 } else { 115 } else {
124 LuanTable list = null; 116 if( !old.isList() ) {
125 if( old instanceof LuanTable ) 117 LuanTable list = new LuanTable(tbl.luan());
126 list = (LuanTable)((LuanTable)old).get(LIST);
127 if( list==null ) {
128 list = new LuanTable(tbl.luan());
129 list.rawAdd(old); 118 list.rawAdd(old);
130 LuanTable wrap = new LuanTable(tbl.luan()); 119 old = list;
131 wrap.put(LIST,list); 120 tbl.put(element.name,old);
132 tbl.put(element.name,wrap);
133 } 121 }
134 list.rawAdd(value); 122 old.rawAdd(t);
135 } 123 }
136 } 124 }
137 return tbl; 125 return tbl;
138 } 126 }
139 127