summary refs log tree commit diff stats
path: root/lib/pure/xmldomparser.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/xmldomparser.nim')
-rw-r--r--lib/pure/xmldomparser.nim110
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)