Mercurial Hosting > luan
comparison src/goodjava/xml/XmlParser.java @ 1790:a8c685a894b4
start xml work
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 25 Dec 2023 23:07:59 -0700 |
parents | 0246add03d11 |
children | 3dabc11da660 |
comparison
equal
deleted
inserted
replaced
1789:bac27b119ff2 | 1790:a8c685a894b4 |
---|---|
3 import java.util.Map; | 3 import java.util.Map; |
4 import java.util.AbstractMap; | 4 import java.util.AbstractMap; |
5 import java.util.LinkedHashMap; | 5 import java.util.LinkedHashMap; |
6 import java.util.List; | 6 import java.util.List; |
7 import java.util.ArrayList; | 7 import java.util.ArrayList; |
8 import java.util.regex.Pattern; | |
9 import java.util.regex.Matcher; | |
8 import goodjava.parser.Parser; | 10 import goodjava.parser.Parser; |
9 import goodjava.parser.ParseException; | 11 import goodjava.parser.ParseException; |
10 | 12 |
11 | 13 |
12 public final class XmlParser { | 14 public final class XmlParser { |
13 | 15 |
14 public static XmlElement parse(String text) throws ParseException { | 16 public static Xml parse(String text) throws ParseException { |
15 return new XmlParser(text).parse(); | 17 return new XmlParser(text).parse(); |
16 } | 18 } |
17 | 19 |
18 private final Parser parser; | 20 private final Parser parser; |
19 | 21 |
23 | 25 |
24 private ParseException exception(String msg) { | 26 private ParseException exception(String msg) { |
25 return new ParseException(parser,msg); | 27 return new ParseException(parser,msg); |
26 } | 28 } |
27 | 29 |
28 private XmlElement parse() throws ParseException { | 30 private Xml parse() throws ParseException { |
29 spaces(); | 31 Xml xml = new Xml(); |
30 prolog(); | 32 spaces(); |
33 xml.declaration = declaration(); | |
31 spaces(); | 34 spaces(); |
32 XmlElement element = element(); | 35 XmlElement element = element(); |
33 spaces(); | 36 spaces(); |
34 if( !parser.endOfInput() ) | 37 if( !parser.endOfInput() ) |
35 throw exception("unexpected text"); | 38 throw exception("unexpected text"); |
36 if( element==null ) | 39 if( element==null ) |
37 throw exception("empty document not allowed"); | 40 throw exception("empty document not allowed"); |
38 return element; | 41 xml.setElement(element); |
39 } | 42 return xml; |
40 | 43 } |
41 private void prolog() throws ParseException { | 44 |
45 private String declaration() throws ParseException { | |
46 int start = parser.begin(); | |
42 if( !parser.match("<?xml") ) | 47 if( !parser.match("<?xml") ) |
43 return; | 48 return parser.failure(null); |
44 while( attribute() != null ); | 49 while( attribute() != null ); |
45 spaces(); | 50 spaces(); |
46 required("?>"); | 51 required("?>"); |
52 String s = parser.textFrom(start); | |
53 return parser.success(s); | |
47 } | 54 } |
48 | 55 |
49 private XmlElement element() throws ParseException { | 56 private XmlElement element() throws ParseException { |
50 parser.begin(); | 57 parser.begin(); |
51 if( !parser.match('<') || parser.test('/') ) | 58 if( !parser.match('<') || parser.test('/') ) |
65 return parser.success(element); | 72 return parser.success(element); |
66 } | 73 } |
67 required(">"); | 74 required(">"); |
68 String s = string(name); | 75 String s = string(name); |
69 if( s != null ) { | 76 if( s != null ) { |
70 XmlElement element = new XmlElement(name,attributes,s); | 77 XmlElement element = new XmlElement(name,attributes); |
78 element.setContent(s); | |
71 return parser.success(element); | 79 return parser.success(element); |
72 } | 80 } |
73 List<XmlElement> elements = elements(name); | 81 List<XmlElement> elements = elements(name); |
74 if( elements != null ) { | 82 if( elements != null ) { |
75 XmlElement element = new XmlElement(name,attributes,elements.toArray(new XmlElement[0])); | 83 XmlElement element = new XmlElement(name,attributes); |
84 element.setContent( elements.toArray(new XmlElement[0]) ); | |
76 return parser.success(element); | 85 return parser.success(element); |
77 } | 86 } |
78 throw exception("bad element"); | 87 throw exception("bad element"); |
79 } | 88 } |
80 | 89 |
175 | 184 |
176 private boolean matchSpace() { | 185 private boolean matchSpace() { |
177 return parser.anyOf(" \t\r\n"); | 186 return parser.anyOf(" \t\r\n"); |
178 } | 187 } |
179 | 188 |
189 private static final Pattern dec = Pattern.compile("&#(\\d+);"); | |
190 | |
180 private static String decode(String s) { | 191 private static String decode(String s) { |
192 Matcher m = dec.matcher(s); | |
193 StringBuffer sb = new StringBuffer(); | |
194 while( m.find() ) { | |
195 String d = m.group(1); | |
196 int i = Integer.parseInt(d); | |
197 d = String.valueOf((char)i); | |
198 m.appendReplacement(sb, d); | |
199 } | |
200 m.appendTail(sb); | |
201 s = sb.toString(); | |
181 s = s.replace("<","<"); | 202 s = s.replace("<","<"); |
182 s = s.replace(">",">"); | 203 s = s.replace(">",">"); |
183 s = s.replace(""","\""); | 204 s = s.replace(""","\""); |
184 s = s.replace("'","'"); | 205 s = s.replace("'","'"); |
185 s = s.replace("&","&"); | 206 s = s.replace("&","&"); |