diff options
Diffstat (limited to 'lib/pure/xmldomparser.nim')
-rw-r--r-- | lib/pure/xmldomparser.nim | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/lib/pure/xmldomparser.nim b/lib/pure/xmldomparser.nim new file mode 100644 index 000000000..90d4d85b1 --- /dev/null +++ b/lib/pure/xmldomparser.nim @@ -0,0 +1,110 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2010 Dominik Picheta +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import xmldom, os, streams, parsexml, strutils + +## This module parses a XML Document into a XML DOM Document representation. + +#XMLDom's Parser - Turns XML into a Document + +type + #Parsing errors + EMismatchedTag* = object of E_Base ## Raised when a tag is not properly closed + +template newException(exceptn, message: expr): expr = + block: # open a new scope + var + e: ref exceptn + new(e) + e.msg = message + e + +proc parseText(x: var TXmlParser, doc: var PDocument): PText = + result = doc.createTextNode(x.charData()) + +proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = + var n = doc.createElement("") + + while True: + case x.kind() + of xmlEof: + break + of xmlElementStart: + if n.tagName() != "": + n.appendChild(parseElement(x, doc)) + else: + n = doc.createElement(x.elementName) + of xmlElementOpen: + if n.tagName() != "": + n.appendChild(parseElement(x, doc)) + else: + if x.elementName.contains(':'): + #TODO: NamespaceURI + n = doc.createElementNS("nil", x.elementName) + else: + n = doc.createElement(x.elementName) + + of xmlElementEnd: + if x.elementName == n.nodeName: + return n + else: #The wrong element is ended + raise newException(EMismatchedTag, "Mismatched tag at line " & + $x.getLine() & " column " & $x.getColumn) + + of xmlCharData: + n.appendChild(parseText(x, doc)) + of xmlAttribute: + if x.attrKey.contains(':'): + #TODO: NamespaceURI + n.setAttributeNS("nil", x.attrKey, x.attrValue) + else: + n.setAttribute(x.attrKey, x.attrValue) + of xmlCData: + n.appendChild(doc.createCDATASection(x.charData())) + of xmlComment: + n.appendChild(doc.createComment(x.charData())) + of xmlPI: + n.appendChild(doc.createProcessingInstruction(x.PIName(), x.PIRest())) + else: + # echo(x.kind()) # XXX do nothing here!? + x.next() + + raise newException(EMismatchedTag, + "Mismatched tag at line " & $x.getLine() & " column " & $x.getColumn) + +proc loadXML*(path: string): PDocument = + ## Loads and parses XML from file specified by ``path``, and returns + ## a ``PDocument`` + + var s = newFileStream(path, fmRead) + if s == nil: raise newException(EIO, "Unable to read file " & path) + + var x: TXmlParser + open(x, s, path, {reportComments}) + + var XmlDoc: PDocument + var DOM: PDOMImplementation = getDOM() + + while True: + x.next() + case x.kind() + of xmlEof: + break + of xmlElementStart, xmlElementOpen: + var el: PElement = parseElement(x, XmlDoc) + XmlDoc = dom.createDocument(el) + else: + # echo(x.kind()) + + return XmlDoc + + +when isMainModule: + var xml = loadXML(r"C:\Users\Dominik\Desktop\Code\Nimrod\xmldom\test.xml") + echo($xml) |