Mercurial Hosting > luan
annotate src/luan/modules/parsers/Xml.java @ 1563:8fbcc4747091
remove LuanFunction.luan
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 09 Nov 2020 01:37:57 -0700 |
parents | b89212fd04b5 |
children | a8c685a894b4 |
rev | line source |
---|---|
1466 | 1 package luan.modules.parsers; |
2 | |
3 import java.util.Collections; | |
4 import java.util.Map; | |
5 import java.util.LinkedHashMap; | |
6 import java.util.List; | |
7 import java.util.ArrayList; | |
8 import goodjava.parser.ParseException; | |
9 import goodjava.xml.XmlElement; | |
10 import goodjava.xml.XmlParser; | |
11 import luan.Luan; | |
12 import luan.LuanTable; | |
13 import luan.LuanException; | |
1495 | 14 import luan.modules.BasicLuan; |
1466 | 15 |
16 | |
17 public final class Xml { | |
18 | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
19 public static String toString(LuanTable tbl) throws LuanException { |
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
20 XmlElement[] elements = elements(tbl); |
1468 | 21 if( elements.length != 1 ) |
22 throw new LuanException("XML must have 1 root element"); | |
23 return elements[0].toString(); | |
1466 | 24 } |
25 | |
1495 | 26 private static final String ATTRIBUTES = "xml_attributes"; |
27 private static final String TEXT = "xml_text"; | |
1468 | 28 |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
29 private static XmlElement[] elements(LuanTable tbl) throws LuanException { |
1468 | 30 List<XmlElement> list = new ArrayList<XmlElement>(); |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
31 for( Map.Entry entry : tbl.rawIterable() ) { |
1468 | 32 Object key = entry.getKey(); |
33 if( !(key instanceof String) ) | |
34 throw new LuanException("XML key must be string"); | |
35 String name = (String)key; | |
36 Object value = entry.getValue(); | |
1495 | 37 if( name.equals(ATTRIBUTES) ) |
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() ) { | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
43 list.add( element(name,t) ); |
1468 | 44 } else { |
1495 | 45 for( Object obj : t.asList() ) { |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
46 list.add( element(name,obj) ); |
1468 | 47 } |
48 } | |
49 } | |
50 return list.toArray(new XmlElement[0]); | |
51 } | |
1466 | 52 |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
53 private static XmlElement element(String name,Object obj) throws LuanException { |
1471 | 54 if( obj instanceof String ) { |
55 return new XmlElement( name, Collections.emptyMap(), (String)obj ); | |
56 } | |
57 LuanTable t = (LuanTable)obj; | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
58 Map<String,String> attributes = attributes(t); |
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
59 String s = (String)t.rawGet(TEXT); |
1471 | 60 if( s != null ) { |
61 return new XmlElement(name,attributes,s); | |
62 } else { | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
63 XmlElement[] elements = elements(t); |
1471 | 64 if( elements.length==0 ) { |
65 return new XmlElement(name,attributes); | |
66 } else { | |
67 return new XmlElement(name,attributes,elements); | |
68 } | |
69 } | |
70 } | |
71 | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
72 private static Map<String,String> attributes(LuanTable tbl) throws LuanException { |
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
73 Object obj = tbl.rawGet(ATTRIBUTES); |
1466 | 74 if( obj==null ) |
75 return Collections.emptyMap(); | |
76 LuanTable t = (LuanTable)obj; | |
77 Map<String,String> map = new LinkedHashMap<String,String>(); | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
78 for( Map.Entry entry : t.rawIterable() ) { |
1466 | 79 String name =(String)entry.getKey(); |
80 String value =(String)entry.getValue(); | |
81 map.put(name,value); | |
82 } | |
83 return map; | |
84 } | |
85 | |
86 | |
1562 | 87 public static LuanTable parse(String s) throws ParseException, LuanException { |
1466 | 88 XmlElement element = XmlParser.parse(s); |
1562 | 89 LuanTable tbl = new LuanTable(); |
1468 | 90 addElements(tbl,new XmlElement[]{element}); |
91 return tbl; | |
1466 | 92 } |
93 | |
1468 | 94 private static LuanTable addElements(LuanTable tbl,XmlElement[] elements) throws LuanException { |
1466 | 95 for( XmlElement element : elements ) { |
1562 | 96 LuanTable t = new LuanTable(); |
1468 | 97 if( !element.attributes.isEmpty() ) { |
1562 | 98 LuanTable attrs = new LuanTable(); |
1468 | 99 for( Map.Entry<String,String> entry : element.attributes.entrySet() ) { |
1562 | 100 attrs.rawPut(entry.getKey(),entry.getValue()); |
1468 | 101 } |
1562 | 102 t.rawPut( ATTRIBUTES, attrs ); |
1468 | 103 } |
104 if( element.content == null ) { | |
1471 | 105 // nothing |
1468 | 106 } else if( element.content instanceof String ) { |
1562 | 107 t.rawPut( TEXT, element.content ); |
1466 | 108 } else { |
109 XmlElement[] els = (XmlElement[])element.content; | |
1468 | 110 addElements(t,els); |
1471 | 111 } |
1562 | 112 LuanTable old = (LuanTable)tbl.rawGet(element.name); |
1471 | 113 if( old==null ) { |
1562 | 114 tbl.rawPut(element.name,t); |
1471 | 115 } else { |
1495 | 116 if( !old.isList() ) { |
1562 | 117 LuanTable list = new LuanTable(); |
1471 | 118 list.rawAdd(old); |
1495 | 119 old = list; |
1562 | 120 tbl.rawPut(element.name,old); |
1471 | 121 } |
1495 | 122 old.rawAdd(t); |
1466 | 123 } |
124 } | |
125 return tbl; | |
126 } | |
127 | |
128 } |