Mercurial Hosting > luan
annotate src/luan/modules/parsers/Xml.java @ 1805:7793bcb5f34a default tip
minor
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 08 May 2024 11:13:16 -0600 |
parents | a8c685a894b4 |
children |
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 ) { |
1790 | 55 XmlElement element = new XmlElement( name, Collections.emptyMap() ); |
56 element.setContent( (String)obj ); | |
57 return element; | |
1471 | 58 } |
59 LuanTable t = (LuanTable)obj; | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
60 Map<String,String> attributes = attributes(t); |
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
61 String s = (String)t.rawGet(TEXT); |
1471 | 62 if( s != null ) { |
1790 | 63 XmlElement element = new XmlElement(name,attributes); |
64 element.setContent(s); | |
65 return element; | |
1471 | 66 } else { |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
67 XmlElement[] elements = elements(t); |
1471 | 68 if( elements.length==0 ) { |
69 return new XmlElement(name,attributes); | |
70 } else { | |
1790 | 71 XmlElement element = new XmlElement(name,attributes); |
72 element.setContent(elements); | |
73 return element; | |
1471 | 74 } |
75 } | |
76 } | |
77 | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
78 private static Map<String,String> attributes(LuanTable tbl) throws LuanException { |
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
79 Object obj = tbl.rawGet(ATTRIBUTES); |
1466 | 80 if( obj==null ) |
81 return Collections.emptyMap(); | |
82 LuanTable t = (LuanTable)obj; | |
83 Map<String,String> map = new LinkedHashMap<String,String>(); | |
1563
8fbcc4747091
remove LuanFunction.luan
Franklin Schmidt <fschmidt@gmail.com>
parents:
1562
diff
changeset
|
84 for( Map.Entry entry : t.rawIterable() ) { |
1466 | 85 String name =(String)entry.getKey(); |
86 String value =(String)entry.getValue(); | |
87 map.put(name,value); | |
88 } | |
89 return map; | |
90 } | |
91 | |
92 | |
1562 | 93 public static LuanTable parse(String s) throws ParseException, LuanException { |
1790 | 94 XmlElement element = XmlParser.parse(s).getElement(); |
1562 | 95 LuanTable tbl = new LuanTable(); |
1468 | 96 addElements(tbl,new XmlElement[]{element}); |
97 return tbl; | |
1466 | 98 } |
99 | |
1468 | 100 private static LuanTable addElements(LuanTable tbl,XmlElement[] elements) throws LuanException { |
1466 | 101 for( XmlElement element : elements ) { |
1562 | 102 LuanTable t = new LuanTable(); |
1468 | 103 if( !element.attributes.isEmpty() ) { |
1562 | 104 LuanTable attrs = new LuanTable(); |
1468 | 105 for( Map.Entry<String,String> entry : element.attributes.entrySet() ) { |
1562 | 106 attrs.rawPut(entry.getKey(),entry.getValue()); |
1468 | 107 } |
1562 | 108 t.rawPut( ATTRIBUTES, attrs ); |
1468 | 109 } |
1790 | 110 Object content = element.getContent(); |
111 if( content == null ) { | |
1471 | 112 // nothing |
1790 | 113 } else if( content instanceof String ) { |
114 t.rawPut( TEXT, content ); | |
1466 | 115 } else { |
1790 | 116 XmlElement[] els = (XmlElement[])content; |
1468 | 117 addElements(t,els); |
1471 | 118 } |
1562 | 119 LuanTable old = (LuanTable)tbl.rawGet(element.name); |
1471 | 120 if( old==null ) { |
1562 | 121 tbl.rawPut(element.name,t); |
1471 | 122 } else { |
1495 | 123 if( !old.isList() ) { |
1562 | 124 LuanTable list = new LuanTable(); |
1471 | 125 list.rawAdd(old); |
1495 | 126 old = list; |
1562 | 127 tbl.rawPut(element.name,old); |
1471 | 128 } |
1495 | 129 old.rawAdd(t); |
1466 | 130 } |
131 } | |
132 return tbl; | |
133 } | |
134 | |
135 } |