XParser is a simple, lightweight XML parser. It may be used as a pull parser by iterating through the element and text sections of an XML stream or it may be used to read an entire XML tree into memory as XElems.
See docLib::Xml
Slots
-
private StrBuf buf := StrBuf()
-
private Str bufToStr()
-
private Bool cdata
- closeSource
-
Bool close()
Close the underlying input stream. Return true if the stream was closed successfully or false if the stream was closed abnormally.
- colSource
-
readonly Int col := 1
Current one based column number.
-
Read from the stream and verify that the next characters match the specified String.
-
private XPi? curPi
-
private XNs? defaultNs
- depthSource
-
readonly Int depth := -1
Get the depth of the current element with the document. A depth of zero indicates the root element. A depth of -1 indicates a position before or after the root element.
- docSource
-
readonly XDoc doc := XDoc()
Get the root document node.
- elemSource
-
XElem? elem()
Get the current element if nodeType is
elemStart
orelemEnd
. If nodeType istext
orpi
then this is the parent element. AfterelemEnd
this XElem instance is no longer valid and will be reused for further processing. If depth is -1 return null. - elemAtSource
-
Get the element at the specified depth. Depth must be between 0 and depth inclusively. Calling
elemAt(0)
will return the root element andelemAt(depth)
returns the current element. If depth is invalid IndexErr is thrown. -
private Bool emptyElem
-
private StrBuf entityBuf := StrBuf()
-
private XErr eosErr()
Make an XIncompleteErr for unexected end of stream.
-
private XErr err(Str msg, Int line := this.line, Int col := this.col)
Make an XException using with current line and column.
-
private InStream in
- lineSource
-
readonly Int line := 1
Current one based line number.
- makeSource
-
new make(InStream in)
Construct input stream to read.
-
private Str? name
-
static private Bool[] nameMap
- nextSource
-
XNodeType? next()
Advance the parser to the next node and return the node type. Return the current node type:
XNodeType.elemStart
XNodeType.elemEnd
XNodeType.text
XNodeType.pi
- null indicates end of stream Also see nodeType.
- nodeTypeSource
-
readonly XNodeType? nodeType
Get the current node type constant which is always the result of the last call to next. Node type will be:
XNodeType.elemStart
XNodeType.elemEnd
XNodeType.text
XNodeType.pi
- null indicates end of stream
-
private XNsDefs[] nsStack := [XNsDefs()]
-
private Bool parseAttr(Int c, XElem elem)
Parse a
[41]
attribute production. We are passed the first character of the attribute name. Return if the attribute had a unresolved namespace prefix. -
private Void parseCDATA()
Parse a CDATA section.
- parseDocSource
-
XDoc parseDoc(Bool close := true)
Parse the entire document into memory as a tree of XElems and optionally close the underlying input stream.
-
private Void parseDocType()
Parse
[28]
DocType := <!DOCTYPE ... > - parseElemSource
-
XElem parseElem(Bool close := true)
Parse the current element entirely into memory as a tree of XElems and optionally close the underlying input stream.
-
private Void parseElemEnd()
Parse an element end production. Next character should be first char of element name.
-
private Void parseElemStart(Int c)
Parse a
[40]
element start production. We are passed the first character after the < (beginning of name). -
private Str parseName(Int c, Bool includeColon)
Parse an XML name token.
-
private Void parsePi()
Parse
[16]
PI := <? ... ?> -
private Void parseProlog()
Parse the prolog up to the root element.
-
private Void parseQName(Int c)
Parse an element or attribute name of the format
[<prefix>:]name
and store result in prefix and name fields. -
private Str parseQuotedStr(Int quote)
Parse a quoted string token "..." or
...
-
Parse a character data text section. Return false if all the text was whitespace only.
- piSource
-
XPi? pi()
if the current node type is
pi
return the XPi instance otherwise return null. -
private Void pop()
Pop decreases the element depth, but leaves the actual element in the stack for reuse. However we do need to re-evaluate our namespace scope if the popped element declared namespaces.
-
private Bool popStack
-
private Str? prefix
-
private XNs prefixToNs(Str prefix, Int line, Int col, Bool checked)
Map the prefix string to a XNs instance declared in the current element or ancestor element. If the prefix cannot be found and checked if false then return
unresolvedNs
, otherwise throw exception. -
private XElem push()
Push a new XElem on the stack. The stack itself only allocates a new XElem the first time a given depth is reached. Further pushes at that depth will always reuse the last XElem from the given depth.
-
private Void pushNs(Str prefix, Str val, Int line, Int col)
Push a namespace onto the stack at the current depth.
-
private Int pushback := -1
-
private Void reEvalDefaultNs()
Recalculate what the default namespace should be because we just popped the element that declared the default namespace last.
-
private Int read()
Read the next character from the stream:
- handle pushbacks
- updates the line and col count
- normalizes line breaks
- throw EOFException if end of stream reached
- skipSource
-
Void skip(Int toDepth := this.depth)
Skip parses all the content until reaching the end tag of the specified depth. When this method returns, the next call to next will return the node immediately following the end tag.
-
private Void skipComment()
Skip
[15]
Comment := <!-- ... --> -
private Bool skipSpace()
Skip
[3]
Space =\n
\r
\t
Return true if one or more space chars found. -
static private Bool[] spaceMap
-
private XElem[] stack := [XElem("")]
- textSource
-
XText? text()
If the current type is
text
the XText instance used to store the character data. After a call to next this XText instance is no longer valid and will be reused for further processing. If the current type is nottext
then return null. -
If the specified char is the amp (&) then resolve the entity otherwise just return the char. If the character is markup then throw an exception.
-
static private Uri unresolvedNs := `__unresolved__`