Add some nil checks for xmldom (and clean up a bit)
This commit is contained in:
parent
779f2b37aa
commit
2c6406703c
1 changed files with 223 additions and 196 deletions
|
|
@ -45,7 +45,7 @@ const
|
||||||
DocumentFragmentNode* = 11
|
DocumentFragmentNode* = 11
|
||||||
|
|
||||||
# Nodes which are childless - Not sure about AttributeNode
|
# Nodes which are childless - Not sure about AttributeNode
|
||||||
childlessObjects = {DocumentNode, AttributeNode, TextNode,
|
childlessObjects = {DocumentNode, AttributeNode, TextNode,
|
||||||
CDataSectionNode, ProcessingInstructionNode, CommentNode}
|
CDataSectionNode, ProcessingInstructionNode, CommentNode}
|
||||||
# Illegal characters
|
# Illegal characters
|
||||||
illegalChars = {'>', '<', '&', '"'}
|
illegalChars = {'>', '<', '&', '"'}
|
||||||
|
|
@ -69,21 +69,21 @@ type
|
||||||
FOwnerDocument: PDocument # Read-Only
|
FOwnerDocument: PDocument # Read-Only
|
||||||
FParentNode: PNode # Read-Only
|
FParentNode: PNode # Read-Only
|
||||||
prefix*: string # Setting this should change some values... TODO!
|
prefix*: string # Setting this should change some values... TODO!
|
||||||
|
|
||||||
PElement* = ref Element
|
PElement* = ref Element
|
||||||
Element = object of Node
|
Element = object of Node
|
||||||
FTagName: string # Read-only
|
FTagName: string # Read-only
|
||||||
|
|
||||||
PCharacterData* = ref CharacterData
|
PCharacterData* = ref CharacterData
|
||||||
CharacterData = object of Node
|
CharacterData = object of Node
|
||||||
data*: string
|
data*: string
|
||||||
|
|
||||||
PDocument* = ref Document
|
PDocument* = ref Document
|
||||||
Document = object of Node
|
Document = object of Node
|
||||||
FImplementation: PDOMImplementation # Read-only
|
FImplementation: PDOMImplementation # Read-only
|
||||||
FDocumentElement: PElement # Read-only
|
FDocumentElement: PElement # Read-only
|
||||||
|
|
||||||
PAttr* = ref Attr
|
PAttr* = ref Attr
|
||||||
Attr = object of Node
|
Attr = object of Node
|
||||||
FName: string # Read-only
|
FName: string # Read-only
|
||||||
FSpecified: bool # Read-only
|
FSpecified: bool # Read-only
|
||||||
|
|
@ -95,13 +95,13 @@ type
|
||||||
|
|
||||||
PText* = ref Text
|
PText* = ref Text
|
||||||
Text = object of CharacterData
|
Text = object of CharacterData
|
||||||
|
|
||||||
PComment* = ref comment
|
PComment* = ref comment
|
||||||
Comment = object of CharacterData
|
Comment = object of CharacterData
|
||||||
|
|
||||||
PCDataSection* = ref CDataSection
|
PCDataSection* = ref CDataSection
|
||||||
CDataSection = object of Text
|
CDataSection = object of Text
|
||||||
|
|
||||||
PProcessingInstruction* = ref ProcessingInstruction
|
PProcessingInstruction* = ref ProcessingInstruction
|
||||||
ProcessingInstruction = object of Node
|
ProcessingInstruction = object of Node
|
||||||
data*: string
|
data*: string
|
||||||
|
|
@ -111,8 +111,8 @@ type
|
||||||
proc getDOM*(): PDOMImplementation =
|
proc getDOM*(): PDOMImplementation =
|
||||||
## Returns a DOMImplementation
|
## Returns a DOMImplementation
|
||||||
new(result)
|
new(result)
|
||||||
result.Features = @[(name: "core", version: "2.0"),
|
result.Features = @[(name: "core", version: "2.0"),
|
||||||
(name: "core", version: "1.0"),
|
(name: "core", version: "1.0"),
|
||||||
(name: "XML", version: "2.0")]
|
(name: "XML", version: "2.0")]
|
||||||
|
|
||||||
proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedName: string): PDocument =
|
proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedName: string): PDocument =
|
||||||
|
|
@ -121,28 +121,28 @@ proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedNam
|
||||||
new(doc)
|
new(doc)
|
||||||
doc.FNamespaceURI = namespaceURI
|
doc.FNamespaceURI = namespaceURI
|
||||||
doc.FImplementation = dom
|
doc.FImplementation = dom
|
||||||
|
|
||||||
var elTag: PElement
|
var elTag: PElement
|
||||||
new(elTag)
|
new(elTag)
|
||||||
elTag.FTagName = qualifiedName
|
elTag.FTagName = qualifiedName
|
||||||
elTag.FNodeName = qualifiedName
|
elTag.FNodeName = qualifiedName
|
||||||
doc.FDocumentElement = elTag
|
doc.FDocumentElement = elTag
|
||||||
doc.FNodeType = DocumentNode
|
doc.FNodeType = DocumentNode
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
proc createDocument*(dom: PDOMImplementation, n: PElement): PDocument =
|
proc createDocument*(dom: PDOMImplementation, n: PElement): PDocument =
|
||||||
## Creates an XML Document object of the specified type with its document element.
|
## Creates an XML Document object of the specified type with its document element.
|
||||||
|
|
||||||
# This procedure is not in the specification, it's provided for the parser.
|
# This procedure is not in the specification, it's provided for the parser.
|
||||||
var doc: PDocument
|
var doc: PDocument
|
||||||
new(doc)
|
new(doc)
|
||||||
doc.FDocumentElement = n
|
doc.FDocumentElement = n
|
||||||
doc.FImplementation = dom
|
doc.FImplementation = dom
|
||||||
doc.FNodeType = DocumentNode
|
doc.FNodeType = DocumentNode
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = ""): bool =
|
proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = ""): bool =
|
||||||
## Returns ``true`` if this ``version`` of the DomImplementation implements ``feature``, otherwise ``false``
|
## Returns ``true`` if this ``version`` of the DomImplementation implements ``feature``, otherwise ``false``
|
||||||
for iName, iVersion in items(dom.Features):
|
for iName, iVersion in items(dom.Features):
|
||||||
|
|
@ -157,58 +157,58 @@ proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = "")
|
||||||
|
|
||||||
# Document
|
# Document
|
||||||
# Attributes
|
# Attributes
|
||||||
|
|
||||||
proc implementation*(doc: PDocument): PDOMImplementation =
|
proc implementation*(doc: PDocument): PDOMImplementation =
|
||||||
return doc.FImplementation
|
return doc.FImplementation
|
||||||
|
|
||||||
proc documentElement*(doc: PDocument): PElement =
|
proc documentElement*(doc: PDocument): PElement =
|
||||||
return doc.FDocumentElement
|
return doc.FDocumentElement
|
||||||
|
|
||||||
# Internal procedures
|
# Internal procedures
|
||||||
proc findNodes(nl: PNode, name: string): seq[PNode] =
|
proc findNodes(nl: PNode, name: string): seq[PNode] =
|
||||||
# Made for getElementsByTagName
|
# Made for getElementsByTagName
|
||||||
var r: seq[PNode] = @[]
|
var r: seq[PNode] = @[]
|
||||||
if isNil(nl.childNodes): return @[]
|
if nl.childNodes == nil: return @[]
|
||||||
if nl.childNodes.len() == 0: return @[]
|
if nl.childNodes.len() == 0: return @[]
|
||||||
|
|
||||||
for i in items(nl.childNodes):
|
for i in items(nl.childNodes):
|
||||||
if i.FNodeType == ElementNode:
|
if i.FNodeType == ElementNode:
|
||||||
if i.FNodeName == name or name == "*":
|
if i.FNodeName == name or name == "*":
|
||||||
r.add(i)
|
r.add(i)
|
||||||
|
|
||||||
if not isNil(i.childNodes):
|
if i.childNodes != nil:
|
||||||
if i.childNodes.len() != 0:
|
if i.childNodes.len() != 0:
|
||||||
r.add(findNodes(i, name))
|
r.add(findNodes(i, name))
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] =
|
proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] =
|
||||||
# Made for getElementsByTagNameNS
|
# Made for getElementsByTagNameNS
|
||||||
var r: seq[PNode] = @[]
|
var r: seq[PNode] = @[]
|
||||||
if isNil(nl.childNodes): return @[]
|
if nl.childNodes == nil: return @[]
|
||||||
if nl.childNodes.len() == 0: return @[]
|
if nl.childNodes.len() == 0: return @[]
|
||||||
|
|
||||||
for i in items(nl.childNodes):
|
for i in items(nl.childNodes):
|
||||||
if i.FNodeType == ElementNode:
|
if i.FNodeType == ElementNode:
|
||||||
if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"):
|
if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"):
|
||||||
r.add(i)
|
r.add(i)
|
||||||
|
|
||||||
if not isNil(i.childNodes):
|
if i.childNodes != nil:
|
||||||
if i.childNodes.len() != 0:
|
if i.childNodes.len() != 0:
|
||||||
r.add(findNodesNS(i, namespaceURI, localName))
|
r.add(findNodesNS(i, namespaceURI, localName))
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
#Procedures
|
#Procedures
|
||||||
proc createAttribute*(doc: PDocument, name: string): PAttr =
|
proc createAttribute*(doc: PDocument, name: string): PAttr =
|
||||||
## Creates an Attr of the given name. Note that the Attr instance can then be set on an Element using the setAttributeNode method.
|
## Creates an Attr of the given name. Note that the Attr instance can then be set on an Element using the setAttributeNode method.
|
||||||
## To create an attribute with a qualified name and namespace URI, use the createAttributeNS method.
|
## To create an attribute with a qualified name and namespace URI, use the createAttributeNS method.
|
||||||
|
|
||||||
# Check if name contains illegal characters
|
# Check if name contains illegal characters
|
||||||
if illegalChars in name:
|
if illegalChars in name:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
||||||
var AttrNode: PAttr
|
var AttrNode: PAttr
|
||||||
new(AttrNode)
|
new(AttrNode)
|
||||||
AttrNode.FName = name
|
AttrNode.FName = name
|
||||||
|
|
@ -222,7 +222,7 @@ proc createAttribute*(doc: PDocument, name: string): PAttr =
|
||||||
|
|
||||||
proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PAttr =
|
proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PAttr =
|
||||||
## Creates an attribute of the given qualified name and namespace URI
|
## Creates an attribute of the given qualified name and namespace URI
|
||||||
|
|
||||||
# Check if name contains illegal characters
|
# Check if name contains illegal characters
|
||||||
if illegalChars in namespaceURI or illegalChars in qualifiedName:
|
if illegalChars in namespaceURI or illegalChars in qualifiedName:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
@ -231,12 +231,12 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str
|
||||||
if namespaceURI == nil:
|
if namespaceURI == nil:
|
||||||
raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
|
raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
|
||||||
elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
|
elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
|
||||||
raise newException(ENamespaceErr,
|
raise newException(ENamespaceErr,
|
||||||
"When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
|
"When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
|
||||||
elif qualifiedName.split(':')[1].toLower() == "xmlns" and namespaceURI != "http://www.w3.org/2000/xmlns/":
|
elif qualifiedName.split(':')[1].toLower() == "xmlns" and namespaceURI != "http://www.w3.org/2000/xmlns/":
|
||||||
raise newException(ENamespaceErr,
|
raise newException(ENamespaceErr,
|
||||||
"When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"")
|
"When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"")
|
||||||
|
|
||||||
var AttrNode: PAttr
|
var AttrNode: PAttr
|
||||||
new(AttrNode)
|
new(AttrNode)
|
||||||
AttrNode.FName = qualifiedName
|
AttrNode.FName = qualifiedName
|
||||||
|
|
@ -250,7 +250,7 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str
|
||||||
AttrNode.prefix = nil
|
AttrNode.prefix = nil
|
||||||
AttrNode.FLocalName = qualifiedName
|
AttrNode.FLocalName = qualifiedName
|
||||||
AttrNode.value = ""
|
AttrNode.value = ""
|
||||||
|
|
||||||
AttrNode.FNodeType = AttributeNode
|
AttrNode.FNodeType = AttributeNode
|
||||||
return AttrNode
|
return AttrNode
|
||||||
|
|
||||||
|
|
@ -265,12 +265,12 @@ proc createCDATASection*(doc: PDocument, data: string): PCDATASection =
|
||||||
return CData
|
return CData
|
||||||
|
|
||||||
proc createComment*(doc: PDocument, data: string): PComment =
|
proc createComment*(doc: PDocument, data: string): PComment =
|
||||||
## Creates a Comment node given the specified string.
|
## Creates a Comment node given the specified string.
|
||||||
var Comm: PComment
|
var Comm: PComment
|
||||||
new(Comm)
|
new(Comm)
|
||||||
Comm.data = data
|
Comm.data = data
|
||||||
Comm.nodeValue = data
|
Comm.nodeValue = data
|
||||||
|
|
||||||
Comm.FNodeType = CommentNode
|
Comm.FNodeType = CommentNode
|
||||||
return Comm
|
return Comm
|
||||||
|
|
||||||
|
|
@ -282,11 +282,11 @@ proc createDocumentFragment*(doc: PDocument): PDocumentFragment =
|
||||||
|
|
||||||
proc createElement*(doc: PDocument, tagName: string): PElement =
|
proc createElement*(doc: PDocument, tagName: string): PElement =
|
||||||
## Creates an element of the type specified.
|
## Creates an element of the type specified.
|
||||||
|
|
||||||
# Check if name contains illegal characters
|
# Check if name contains illegal characters
|
||||||
if illegalChars in tagName:
|
if illegalChars in tagName:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
||||||
var elNode: PElement
|
var elNode: PElement
|
||||||
new(elNode)
|
new(elNode)
|
||||||
elNode.FTagName = tagName
|
elNode.FTagName = tagName
|
||||||
|
|
@ -296,9 +296,9 @@ proc createElement*(doc: PDocument, tagName: string): PElement =
|
||||||
elNode.FNamespaceURI = nil
|
elNode.FNamespaceURI = nil
|
||||||
elNode.childNodes = @[]
|
elNode.childNodes = @[]
|
||||||
elNode.attributes = @[]
|
elNode.attributes = @[]
|
||||||
|
|
||||||
elNode.FNodeType = ElementNode
|
elNode.FNodeType = ElementNode
|
||||||
|
|
||||||
return elNode
|
return elNode
|
||||||
|
|
||||||
proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PElement =
|
proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PElement =
|
||||||
|
|
@ -307,13 +307,13 @@ proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: strin
|
||||||
if namespaceURI == nil:
|
if namespaceURI == nil:
|
||||||
raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
|
raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil")
|
||||||
elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
|
elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace":
|
||||||
raise newException(ENamespaceErr,
|
raise newException(ENamespaceErr,
|
||||||
"When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
|
"When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
|
||||||
|
|
||||||
# Check if name contains illegal characters
|
# Check if name contains illegal characters
|
||||||
if illegalChars in namespaceURI or illegalChars in qualifiedName:
|
if illegalChars in namespaceURI or illegalChars in qualifiedName:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
||||||
var elNode: PElement
|
var elNode: PElement
|
||||||
new(elNode)
|
new(elNode)
|
||||||
elNode.FTagName = qualifiedName
|
elNode.FTagName = qualifiedName
|
||||||
|
|
@ -327,18 +327,18 @@ proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: strin
|
||||||
elNode.FNamespaceURI = namespaceURI
|
elNode.FNamespaceURI = namespaceURI
|
||||||
elNode.childNodes = @[]
|
elNode.childNodes = @[]
|
||||||
elNode.attributes = @[]
|
elNode.attributes = @[]
|
||||||
|
|
||||||
elNode.FNodeType = ElementNode
|
elNode.FNodeType = ElementNode
|
||||||
|
|
||||||
return elNode
|
return elNode
|
||||||
|
|
||||||
proc createProcessingInstruction*(doc: PDocument, target: string, data: string): PProcessingInstruction =
|
proc createProcessingInstruction*(doc: PDocument, target: string, data: string): PProcessingInstruction =
|
||||||
## Creates a ProcessingInstruction node given the specified name and data strings.
|
## Creates a ProcessingInstruction node given the specified name and data strings.
|
||||||
|
|
||||||
#Check if name contains illegal characters
|
#Check if name contains illegal characters
|
||||||
if illegalChars in target:
|
if illegalChars in target:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
||||||
var PI: PProcessingInstruction
|
var PI: PProcessingInstruction
|
||||||
new(PI)
|
new(PI)
|
||||||
PI.FTarget = target
|
PI.FTarget = target
|
||||||
|
|
@ -347,13 +347,13 @@ proc createProcessingInstruction*(doc: PDocument, target: string, data: string):
|
||||||
return PI
|
return PI
|
||||||
|
|
||||||
proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode
|
proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode
|
||||||
## Creates a Text node given the specified string.
|
## Creates a Text node given the specified string.
|
||||||
var txtNode: PText
|
var txtNode: PText
|
||||||
new(txtNode)
|
new(txtNode)
|
||||||
txtNode.data = data
|
txtNode.data = data
|
||||||
txtNode.nodeValue = data
|
txtNode.nodeValue = data
|
||||||
txtNode.FNodeName = "#text"
|
txtNode.FNodeName = "#text"
|
||||||
|
|
||||||
txtNode.FNodeType = TextNode
|
txtNode.FNodeType = TextNode
|
||||||
return txtNode
|
return txtNode
|
||||||
|
|
||||||
|
|
@ -363,22 +363,22 @@ discard """proc getElementById*(doc: PDocument, elementId: string): PElement =
|
||||||
|
|
||||||
proc getElementsByTagName*(doc: PDocument, tagName: string): seq[PNode] =
|
proc getElementsByTagName*(doc: PDocument, tagName: string): seq[PNode] =
|
||||||
## Returns a NodeList of all the Elements with a given tag name in
|
## Returns a NodeList of all the Elements with a given tag name in
|
||||||
## the order in which they are encountered in a preorder traversal of the Document tree.
|
## the order in which they are encountered in a preorder traversal of the Document tree.
|
||||||
var result: seq[PNode] = @[]
|
var result: seq[PNode] = @[]
|
||||||
if doc.FDocumentElement.FNodeName == tagName or tagName == "*":
|
if doc.FDocumentElement.FNodeName == tagName or tagName == "*":
|
||||||
result.add(doc.FDocumentElement)
|
result.add(doc.FDocumentElement)
|
||||||
|
|
||||||
result.add(doc.FDocumentElement.findNodes(tagName))
|
result.add(doc.FDocumentElement.findNodes(tagName))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
proc getElementsByTagNameNS*(doc: PDocument, namespaceURI: string, localName: string): seq[PNode] =
|
proc getElementsByTagNameNS*(doc: PDocument, namespaceURI: string, localName: string): seq[PNode] =
|
||||||
## Returns a NodeList of all the Elements with a given localName and namespaceURI
|
## Returns a NodeList of all the Elements with a given localName and namespaceURI
|
||||||
## in the order in which they are encountered in a preorder traversal of the Document tree.
|
## in the order in which they are encountered in a preorder traversal of the Document tree.
|
||||||
var result: seq[PNode] = @[]
|
var result: seq[PNode] = @[]
|
||||||
if doc.FDocumentElement.FLocalName == localName or localName == "*":
|
if doc.FDocumentElement.FLocalName == localName or localName == "*":
|
||||||
if doc.FDocumentElement.FNamespaceURI == namespaceURI or namespaceURI == "*":
|
if doc.FDocumentElement.FNamespaceURI == namespaceURI or namespaceURI == "*":
|
||||||
result.add(doc.FDocumentElement)
|
result.add(doc.FDocumentElement)
|
||||||
|
|
||||||
result.add(doc.FDocumentElement.findNodesNS(namespaceURI, localName))
|
result.add(doc.FDocumentElement.findNodesNS(namespaceURI, localName))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
@ -406,7 +406,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
|
||||||
if deep:
|
if deep:
|
||||||
for i in low(tmp.len())..high(tmp.len()):
|
for i in low(tmp.len())..high(tmp.len()):
|
||||||
n.childNodes.add(importNode(doc, tmp[i], deep))
|
n.childNodes.add(importNode(doc, tmp[i], deep))
|
||||||
|
|
||||||
return n
|
return n
|
||||||
of ElementNode:
|
of ElementNode:
|
||||||
var n: PNode
|
var n: PNode
|
||||||
|
|
@ -414,7 +414,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
|
||||||
n = importedNode
|
n = importedNode
|
||||||
n.FOwnerDocument = doc
|
n.FOwnerDocument = doc
|
||||||
n.FParentNode = nil
|
n.FParentNode = nil
|
||||||
|
|
||||||
var tmpA: seq[PAttr] = n.attributes
|
var tmpA: seq[PAttr] = n.attributes
|
||||||
n.attributes = @[]
|
n.attributes = @[]
|
||||||
# Import the Element node's attributes
|
# Import the Element node's attributes
|
||||||
|
|
@ -426,7 +426,7 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
|
||||||
if deep:
|
if deep:
|
||||||
for i in low(tmp.len())..high(tmp.len()):
|
for i in low(tmp.len())..high(tmp.len()):
|
||||||
n.childNodes.add(importNode(doc, tmp[i], deep))
|
n.childNodes.add(importNode(doc, tmp[i], deep))
|
||||||
|
|
||||||
return n
|
return n
|
||||||
of ProcessingInstructionNode, TextNode, CDataSectionNode, CommentNode:
|
of ProcessingInstructionNode, TextNode, CDataSectionNode, CommentNode:
|
||||||
var n: PNode
|
var n: PNode
|
||||||
|
|
@ -437,27 +437,27 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode =
|
||||||
return n
|
return n
|
||||||
else:
|
else:
|
||||||
raise newException(ENotSupportedErr, "The type of node being imported is not supported")
|
raise newException(ENotSupportedErr, "The type of node being imported is not supported")
|
||||||
|
|
||||||
|
|
||||||
# Node
|
# Node
|
||||||
# Attributes
|
# Attributes
|
||||||
|
|
||||||
proc firstChild*(n: PNode): PNode =
|
proc firstChild*(n: PNode): PNode =
|
||||||
## Returns this node's first child
|
## Returns this node's first child
|
||||||
|
|
||||||
if n.childNodes.len() > 0:
|
if n.childNodes != nil and n.childNodes.len() > 0:
|
||||||
return n.childNodes[0]
|
return n.childNodes[0]
|
||||||
else:
|
else:
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc lastChild*(n: PNode): PNode =
|
proc lastChild*(n: PNode): PNode =
|
||||||
## Returns this node's last child
|
## Returns this node's last child
|
||||||
|
|
||||||
if n.childNodes.len() > 0:
|
if n.childNodes != nil and n.childNodes.len() > 0:
|
||||||
return n.childNodes[n.childNodes.len() - 1]
|
return n.childNodes[n.childNodes.len() - 1]
|
||||||
else:
|
else:
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc localName*(n: PNode): string =
|
proc localName*(n: PNode): string =
|
||||||
## Returns this nodes local name
|
## Returns this nodes local name
|
||||||
|
|
||||||
|
|
@ -465,15 +465,17 @@ proc localName*(n: PNode): string =
|
||||||
|
|
||||||
proc namespaceURI*(n: PNode): string =
|
proc namespaceURI*(n: PNode): string =
|
||||||
## Returns this nodes namespace URI
|
## Returns this nodes namespace URI
|
||||||
|
|
||||||
return n.FNamespaceURI
|
return n.FNamespaceURI
|
||||||
|
|
||||||
proc `namespaceURI=`*(n: PNode, value: string) =
|
proc `namespaceURI=`*(n: PNode, value: string) =
|
||||||
n.FNamespaceURI = value
|
n.FNamespaceURI = value
|
||||||
|
|
||||||
proc nextSibling*(n: PNode): PNode =
|
proc nextSibling*(n: PNode): PNode =
|
||||||
## Returns the next sibling of this node
|
## Returns the next sibling of this node
|
||||||
|
|
||||||
|
if n.FParentNode == nil or n.FParentNode.childNodes == nil:
|
||||||
|
return nil
|
||||||
var nLow: int = low(n.FParentNode.childNodes)
|
var nLow: int = low(n.FParentNode.childNodes)
|
||||||
var nHigh: int = high(n.FParentNode.childNodes)
|
var nHigh: int = high(n.FParentNode.childNodes)
|
||||||
for i in nLow..nHigh:
|
for i in nLow..nHigh:
|
||||||
|
|
@ -500,17 +502,19 @@ proc parentNode*(n: PNode): PNode =
|
||||||
## Returns the parent node of this node
|
## Returns the parent node of this node
|
||||||
|
|
||||||
return n.FParentNode
|
return n.FParentNode
|
||||||
|
|
||||||
proc previousSibling*(n: PNode): PNode =
|
proc previousSibling*(n: PNode): PNode =
|
||||||
## Returns the previous sibling of this node
|
## Returns the previous sibling of this node
|
||||||
|
|
||||||
|
if n.FParentNode == nil or n.FParentNode.childNodes == nil:
|
||||||
|
return nil
|
||||||
var nLow: int = low(n.FParentNode.childNodes)
|
var nLow: int = low(n.FParentNode.childNodes)
|
||||||
var nHigh: int = high(n.FParentNode.childNodes)
|
var nHigh: int = high(n.FParentNode.childNodes)
|
||||||
for i in nLow..nHigh:
|
for i in nLow..nHigh:
|
||||||
if n.FParentNode.childNodes[i] == n:
|
if n.FParentNode.childNodes[i] == n:
|
||||||
return n.FParentNode.childNodes[i - 1]
|
return n.FParentNode.childNodes[i - 1]
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc `prefix=`*(n: PNode, value: string) =
|
proc `prefix=`*(n: PNode, value: string) =
|
||||||
## Modifies the prefix of this node
|
## Modifies the prefix of this node
|
||||||
|
|
||||||
|
|
@ -522,10 +526,10 @@ proc `prefix=`*(n: PNode, value: string) =
|
||||||
if n.FNamespaceURI == nil:
|
if n.FNamespaceURI == nil:
|
||||||
raise newException(ENamespaceErr, "namespaceURI cannot be nil")
|
raise newException(ENamespaceErr, "namespaceURI cannot be nil")
|
||||||
elif value.toLower() == "xml" and n.FNamespaceURI != "http://www.w3.org/XML/1998/namespace":
|
elif value.toLower() == "xml" and n.FNamespaceURI != "http://www.w3.org/XML/1998/namespace":
|
||||||
raise newException(ENamespaceErr,
|
raise newException(ENamespaceErr,
|
||||||
"When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
|
"When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"")
|
||||||
elif value.toLower() == "xmlns" and n.FNamespaceURI != "http://www.w3.org/2000/xmlns/":
|
elif value.toLower() == "xmlns" and n.FNamespaceURI != "http://www.w3.org/2000/xmlns/":
|
||||||
raise newException(ENamespaceErr,
|
raise newException(ENamespaceErr,
|
||||||
"When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"")
|
"When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"")
|
||||||
elif value.toLower() == "xmlns" and n.FNodeType == AttributeNode:
|
elif value.toLower() == "xmlns" and n.FNodeType == AttributeNode:
|
||||||
raise newException(ENamespaceErr, "An AttributeNode cannot have a prefix of \"xmlns\"")
|
raise newException(ENamespaceErr, "An AttributeNode cannot have a prefix of \"xmlns\"")
|
||||||
|
|
@ -543,33 +547,33 @@ proc `prefix=`*(n: PNode, value: string) =
|
||||||
proc appendChild*(n: PNode, newChild: PNode) =
|
proc appendChild*(n: PNode, newChild: PNode) =
|
||||||
## Adds the node newChild to the end of the list of children of this node.
|
## Adds the node newChild to the end of the list of children of this node.
|
||||||
## If the newChild is already in the tree, it is first removed.
|
## If the newChild is already in the tree, it is first removed.
|
||||||
|
|
||||||
# Check if n contains newChild
|
# Check if n contains newChild
|
||||||
if not IsNil(n.childNodes):
|
if n.childNodes != nil:
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
if n.childNodes[i] == newChild:
|
if n.childNodes[i] == newChild:
|
||||||
raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.")
|
raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.")
|
||||||
|
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if n.FOwnerDocument != newChild.FOwnerDocument:
|
if n.FOwnerDocument != newChild.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
if n == newChild:
|
if n == newChild:
|
||||||
raise newException(EHierarchyRequestErr, "You can't add a node into itself")
|
raise newException(EHierarchyRequestErr, "You can't add a node into itself")
|
||||||
|
|
||||||
if n.nodeType in childlessObjects:
|
if n.nodeType in childlessObjects:
|
||||||
raise newException(ENoModificationAllowedErr, "Cannot append children to a childless node")
|
raise newException(ENoModificationAllowedErr, "Cannot append children to a childless node")
|
||||||
|
|
||||||
if isNil(n.childNodes): n.childNodes = @[]
|
if n.childNodes == nil: n.childNodes = @[]
|
||||||
|
|
||||||
newChild.FParentNode = n
|
newChild.FParentNode = n
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
if n.childNodes[i] == newChild:
|
if n.childNodes[i] == newChild:
|
||||||
n.childNodes[i] = newChild
|
n.childNodes[i] = newChild
|
||||||
|
|
||||||
n.childNodes.add(newChild)
|
n.childNodes.add(newChild)
|
||||||
|
|
||||||
proc cloneNode*(n: PNode, deep: bool): PNode =
|
proc cloneNode*(n: PNode, deep: bool): PNode =
|
||||||
## Returns a duplicate of this node, if ``deep`` is `true`, Element node's children are copied
|
## Returns a duplicate of this node, if ``deep`` is `true`, Element node's children are copied
|
||||||
case n.FNodeType
|
case n.FNodeType
|
||||||
of AttributeNode:
|
of AttributeNode:
|
||||||
|
|
@ -586,7 +590,7 @@ proc cloneNode*(n: PNode, deep: bool): PNode =
|
||||||
# Import the childNodes
|
# Import the childNodes
|
||||||
var tmp: seq[PNode] = n.childNodes
|
var tmp: seq[PNode] = n.childNodes
|
||||||
n.childNodes = @[]
|
n.childNodes = @[]
|
||||||
if deep:
|
if deep and tmp != nil:
|
||||||
for i in low(tmp.len())..high(tmp.len()):
|
for i in low(tmp.len())..high(tmp.len()):
|
||||||
n.childNodes.add(cloneNode(tmp[i], deep))
|
n.childNodes.add(cloneNode(tmp[i], deep))
|
||||||
return newNode
|
return newNode
|
||||||
|
|
@ -597,29 +601,34 @@ proc cloneNode*(n: PNode, deep: bool): PNode =
|
||||||
return newNode
|
return newNode
|
||||||
|
|
||||||
proc hasAttributes*(n: PNode): bool =
|
proc hasAttributes*(n: PNode): bool =
|
||||||
## Returns whether this node (if it is an element) has any attributes.
|
## Returns whether this node (if it is an element) has any attributes.
|
||||||
return n.attributes.len() > 0
|
return n.attributes != nil and n.attributes.len() > 0
|
||||||
|
|
||||||
proc hasChildNodes*(n: PNode): bool =
|
proc hasChildNodes*(n: PNode): bool =
|
||||||
## Returns whether this node has any children.
|
## Returns whether this node has any children.
|
||||||
return n.childNodes.len() > 0
|
return n.childNodes != nil and n.childNodes.len() > 0
|
||||||
|
|
||||||
proc insertBefore*(n: PNode, newChild: PNode, refChild: PNode): PNode =
|
proc insertBefore*(n: PNode, newChild: PNode, refChild: PNode): PNode =
|
||||||
## Inserts the node ``newChild`` before the existing child node ``refChild``.
|
## Inserts the node ``newChild`` before the existing child node ``refChild``.
|
||||||
## If ``refChild`` is nil, insert ``newChild`` at the end of the list of children.
|
## If ``refChild`` is nil, insert ``newChild`` at the end of the list of children.
|
||||||
|
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if n.FOwnerDocument != newChild.FOwnerDocument:
|
if n.FOwnerDocument != newChild.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
|
if n.childNodes == nil:
|
||||||
|
n.ChildNodes = @[]
|
||||||
|
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
if n.childNodes[i] == refChild:
|
if n.childNodes[i] == refChild:
|
||||||
n.childNodes.insert(newChild, i - 1)
|
n.childNodes.insert(newChild, i - 1)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
n.ChildNodes.add(newChild)
|
||||||
|
|
||||||
proc isSupported*(n: PNode, feature: string, version: string): bool =
|
proc isSupported*(n: PNode, feature: string, version: string): bool =
|
||||||
## Tests whether the DOM implementation implements a specific
|
## Tests whether the DOM implementation implements a specific
|
||||||
## feature and that feature is supported by this node.
|
## feature and that feature is supported by this node.
|
||||||
return n.FOwnerDocument.FImplementation.hasFeature(feature, version)
|
return n.FOwnerDocument.FImplementation.hasFeature(feature, version)
|
||||||
|
|
||||||
proc isEmpty(s: string): bool =
|
proc isEmpty(s: string): bool =
|
||||||
|
|
@ -635,17 +644,17 @@ proc normalize*(n: PNode) =
|
||||||
## Merges all seperated TextNodes together, and removes any empty TextNodes
|
## Merges all seperated TextNodes together, and removes any empty TextNodes
|
||||||
var curTextNode: PNode = nil
|
var curTextNode: PNode = nil
|
||||||
var i: int = 0
|
var i: int = 0
|
||||||
|
|
||||||
var newChildNodes: seq[PNode] = @[]
|
var newChildNodes: seq[PNode] = @[]
|
||||||
while True:
|
while True:
|
||||||
if i >= n.childNodes.len:
|
if n.childNodes == nil or i >= n.childNodes.len:
|
||||||
break
|
break
|
||||||
if n.childNodes[i].nodeType == TextNode:
|
if n.childNodes[i].nodeType == TextNode:
|
||||||
|
|
||||||
#If the TextNode is empty, remove it
|
#If the TextNode is empty, remove it
|
||||||
if PText(n.childNodes[i]).data.isEmpty():
|
if PText(n.childNodes[i]).data.isEmpty():
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
if curTextNode == nil:
|
if curTextNode == nil:
|
||||||
curTextNode = n.childNodes[i]
|
curTextNode = n.childNodes[i]
|
||||||
else:
|
else:
|
||||||
|
|
@ -656,35 +665,37 @@ proc normalize*(n: PNode) =
|
||||||
newChildNodes.add(curTextNode)
|
newChildNodes.add(curTextNode)
|
||||||
newChildNodes.add(n.childNodes[i])
|
newChildNodes.add(n.childNodes[i])
|
||||||
curTextNode = nil
|
curTextNode = nil
|
||||||
|
|
||||||
inc(i)
|
inc(i)
|
||||||
n.childNodes = newChildNodes
|
n.childNodes = newChildNodes
|
||||||
|
|
||||||
proc removeChild*(n: PNode, oldChild: PNode): PNode =
|
proc removeChild*(n: PNode, oldChild: PNode): PNode =
|
||||||
## Removes the child node indicated by ``oldChild`` from the list of children, and returns it.
|
## Removes the child node indicated by ``oldChild`` from the list of children, and returns it.
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
if n.childNodes != nil:
|
||||||
if n.childNodes[i] == oldChild:
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
result = n.childNodes[i]
|
if n.childNodes[i] == oldChild:
|
||||||
n.childNodes.delete(i)
|
result = n.childNodes[i]
|
||||||
return result
|
n.childNodes.delete(i)
|
||||||
|
return result
|
||||||
|
|
||||||
raise newException(ENotFoundErr, "Node not found")
|
raise newException(ENotFoundErr, "Node not found")
|
||||||
|
|
||||||
proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode =
|
proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode =
|
||||||
## Replaces the child node ``oldChild`` with ``newChild`` in the list of children, and returns the ``oldChild`` node.
|
## Replaces the child node ``oldChild`` with ``newChild`` in the list of children, and returns the ``oldChild`` node.
|
||||||
|
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if n.FOwnerDocument != newChild.FOwnerDocument:
|
if n.FOwnerDocument != newChild.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
for i in low(n.childNodes)..high(n.childNodes):
|
if n.childNodes != nil:
|
||||||
if n.childNodes[i] == oldChild:
|
for i in low(n.childNodes)..high(n.childNodes):
|
||||||
result = n.childNodes[i]
|
if n.childNodes[i] == oldChild:
|
||||||
n.childNodes[i] = newChild
|
result = n.childNodes[i]
|
||||||
return result
|
n.childNodes[i] = newChild
|
||||||
|
return result
|
||||||
|
|
||||||
raise newException(ENotFoundErr, "Node not found")
|
raise newException(ENotFoundErr, "Node not found")
|
||||||
|
|
||||||
# NamedNodeMap
|
# NamedNodeMap
|
||||||
|
|
||||||
proc getNamedItem*(NList: seq[PNode], name: string): PNode =
|
proc getNamedItem*(NList: seq[PNode], name: string): PNode =
|
||||||
|
|
@ -693,22 +704,22 @@ proc getNamedItem*(NList: seq[PNode], name: string): PNode =
|
||||||
if i.nodeName() == name:
|
if i.nodeName() == name:
|
||||||
return i
|
return i
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc getNamedItem*(NList: seq[PAttr], name: string): PAttr =
|
proc getNamedItem*(NList: seq[PAttr], name: string): PAttr =
|
||||||
## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil``
|
## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil``
|
||||||
for i in items(NList):
|
for i in items(NList):
|
||||||
if i.nodeName() == name:
|
if i.nodeName() == name:
|
||||||
return i
|
return i
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc getNamedItemNS*(NList: seq[PNode], namespaceURI: string, localName: string): PNode =
|
proc getNamedItemNS*(NList: seq[PNode], namespaceURI: string, localName: string): PNode =
|
||||||
## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil``
|
## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil``
|
||||||
for i in items(NList):
|
for i in items(NList):
|
||||||
if i.namespaceURI() == namespaceURI and i.localName() == localName:
|
if i.namespaceURI() == namespaceURI and i.localName() == localName:
|
||||||
return i
|
return i
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string): PAttr =
|
proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string): PAttr =
|
||||||
## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil``
|
## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil``
|
||||||
for i in items(NList):
|
for i in items(NList):
|
||||||
if i.NamespaceURI() == namespaceURI and i.LocalName() == localName:
|
if i.NamespaceURI() == namespaceURI and i.LocalName() == localName:
|
||||||
|
|
@ -716,7 +727,7 @@ proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string)
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc item*(NList: seq[PNode], index: int): PNode =
|
proc item*(NList: seq[PNode], index: int): PNode =
|
||||||
## Returns the ``index`` th item in the map.
|
## Returns the ``index`` th item in the map.
|
||||||
## If ``index`` is greater than or equal to the number of nodes in this map, this returns ``nil``.
|
## If ``index`` is greater than or equal to the number of nodes in this map, this returns ``nil``.
|
||||||
if index >= NList.len(): return nil
|
if index >= NList.len(): return nil
|
||||||
else: return NList[index]
|
else: return NList[index]
|
||||||
|
|
@ -729,9 +740,9 @@ proc removeNamedItem*(NList: var seq[PNode], name: string): PNode =
|
||||||
result = NList[i]
|
result = NList[i]
|
||||||
NList.delete(i)
|
NList.delete(i)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
raise newException(ENotFoundErr, "Node not found")
|
raise newException(ENotFoundErr, "Node not found")
|
||||||
|
|
||||||
proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName: string): PNode =
|
proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName: string): PNode =
|
||||||
## Removes a node specified by local name and namespace URI
|
## Removes a node specified by local name and namespace URI
|
||||||
for i in low(NList)..high(NList):
|
for i in low(NList)..high(NList):
|
||||||
|
|
@ -739,19 +750,19 @@ proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName:
|
||||||
result = NList[i]
|
result = NList[i]
|
||||||
NList.delete(i)
|
NList.delete(i)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
raise newException(ENotFoundErr, "Node not found")
|
raise newException(ENotFoundErr, "Node not found")
|
||||||
|
|
||||||
proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
|
proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
|
||||||
## Adds ``arg`` as a ``Node`` to the ``NList``
|
## Adds ``arg`` as a ``Node`` to the ``NList``
|
||||||
## If a node with the same name is already present in this map, it is replaced by the new one.
|
## If a node with the same name is already present in this map, it is replaced by the new one.
|
||||||
if not isNil(NList):
|
if NList != nil:
|
||||||
if NList.len() > 0:
|
if NList.len() > 0:
|
||||||
#Check if newChild is from this nodes document
|
#Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
#Exceptions End
|
#Exceptions End
|
||||||
|
|
||||||
var item: PNode = NList.getNamedItem(arg.NodeName())
|
var item: PNode = NList.getNamedItem(arg.NodeName())
|
||||||
if item == nil:
|
if item == nil:
|
||||||
NList.add(arg)
|
NList.add(arg)
|
||||||
|
|
@ -765,19 +776,19 @@ proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode =
|
||||||
break
|
break
|
||||||
NList[index] = arg
|
NList[index] = arg
|
||||||
return item # Return the replaced node
|
return item # Return the replaced node
|
||||||
|
|
||||||
proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
||||||
## Adds ``arg`` as a ``Node`` to the ``NList``
|
## Adds ``arg`` as a ``Node`` to the ``NList``
|
||||||
## If a node with the same name is already present in this map, it is replaced by the new one.
|
## If a node with the same name is already present in this map, it is replaced by the new one.
|
||||||
if not IsNil(NList):
|
if NList != nil:
|
||||||
if NList.len() > 0:
|
if NList.len() > 0:
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
if arg.FOwnerElement != nil:
|
if arg.FOwnerElement != nil:
|
||||||
raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode")
|
raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode")
|
||||||
|
|
||||||
# Exceptions end
|
# Exceptions end
|
||||||
var item: PAttr = NList.getNamedItem(arg.nodeName())
|
var item: PAttr = NList.getNamedItem(arg.nodeName())
|
||||||
if item == nil:
|
if item == nil:
|
||||||
|
|
@ -792,16 +803,16 @@ proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
||||||
break
|
break
|
||||||
NList[index] = arg
|
NList[index] = arg
|
||||||
return item # Return the replaced node
|
return item # Return the replaced node
|
||||||
|
|
||||||
proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
|
proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
|
||||||
## Adds a node using its ``namespaceURI`` and ``localName``
|
## Adds a node using its ``namespaceURI`` and ``localName``
|
||||||
if not IsNil(NList):
|
if NList != nil:
|
||||||
if NList.len() > 0:
|
if NList.len() > 0:
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
#Exceptions end
|
#Exceptions end
|
||||||
|
|
||||||
var item: PNode = NList.getNamedItemNS(arg.namespaceURI(), arg.localName())
|
var item: PNode = NList.getNamedItemNS(arg.namespaceURI(), arg.localName())
|
||||||
if item == nil:
|
if item == nil:
|
||||||
NList.add(arg)
|
NList.add(arg)
|
||||||
|
|
@ -815,18 +826,18 @@ proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode =
|
||||||
break
|
break
|
||||||
NList[index] = arg
|
NList[index] = arg
|
||||||
return item # Return the replaced node
|
return item # Return the replaced node
|
||||||
|
|
||||||
proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
||||||
## Adds a node using its ``namespaceURI`` and ``localName``
|
## Adds a node using its ``namespaceURI`` and ``localName``
|
||||||
if not isNil(NList):
|
if NList != nil:
|
||||||
if NList.len() > 0:
|
if NList.len() > 0:
|
||||||
# Check if newChild is from this nodes document
|
# Check if newChild is from this nodes document
|
||||||
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
if NList[0].FOwnerDocument != arg.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
if arg.FOwnerElement != nil:
|
if arg.FOwnerElement != nil:
|
||||||
raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode")
|
raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode")
|
||||||
|
|
||||||
# Exceptions end
|
# Exceptions end
|
||||||
var item: PAttr = NList.getNamedItemNS(arg.namespaceURI(), arg.localName())
|
var item: PAttr = NList.getNamedItemNS(arg.namespaceURI(), arg.localName())
|
||||||
if item == nil:
|
if item == nil:
|
||||||
|
|
@ -841,8 +852,8 @@ proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr =
|
||||||
break
|
break
|
||||||
NList[index] = arg
|
NList[index] = arg
|
||||||
return item # Return the replaced node
|
return item # Return the replaced node
|
||||||
|
|
||||||
# CharacterData - Decided to implement this,
|
# CharacterData - Decided to implement this,
|
||||||
# Didn't add the procedures, because you can just edit .data
|
# Didn't add the procedures, because you can just edit .data
|
||||||
|
|
||||||
# Attr
|
# Attr
|
||||||
|
|
@ -851,13 +862,13 @@ proc name*(a: PAttr): string =
|
||||||
## Returns the name of the Attribute
|
## Returns the name of the Attribute
|
||||||
|
|
||||||
return a.FName
|
return a.FName
|
||||||
|
|
||||||
proc specified*(a: PAttr): bool =
|
proc specified*(a: PAttr): bool =
|
||||||
## Specifies whether this attribute was specified in the original document
|
## Specifies whether this attribute was specified in the original document
|
||||||
|
|
||||||
return a.FSpecified
|
return a.FSpecified
|
||||||
|
|
||||||
proc ownerElement*(a: PAttr): PElement =
|
proc ownerElement*(a: PAttr): PElement =
|
||||||
## Returns this Attributes owner element
|
## Returns this Attributes owner element
|
||||||
|
|
||||||
return a.FOwnerElement
|
return a.FOwnerElement
|
||||||
|
|
@ -873,6 +884,8 @@ proc tagName*(el: PElement): string =
|
||||||
# Procedures
|
# Procedures
|
||||||
proc getAttribute*(el: PElement, name: string): string =
|
proc getAttribute*(el: PElement, name: string): string =
|
||||||
## Retrieves an attribute value by ``name``
|
## Retrieves an attribute value by ``name``
|
||||||
|
if el.attributes == nil:
|
||||||
|
return nil
|
||||||
var attribute = el.attributes.getNamedItem(name)
|
var attribute = el.attributes.getNamedItem(name)
|
||||||
if attribute != nil:
|
if attribute != nil:
|
||||||
return attribute.value
|
return attribute.value
|
||||||
|
|
@ -881,19 +894,25 @@ proc getAttribute*(el: PElement, name: string): string =
|
||||||
|
|
||||||
proc getAttributeNS*(el: PElement, namespaceURI: string, localName: string): string =
|
proc getAttributeNS*(el: PElement, namespaceURI: string, localName: string): string =
|
||||||
## Retrieves an attribute value by ``localName`` and ``namespaceURI``
|
## Retrieves an attribute value by ``localName`` and ``namespaceURI``
|
||||||
|
if el.attributes == nil:
|
||||||
|
return nil
|
||||||
var attribute = el.attributes.getNamedItemNS(namespaceURI, localName)
|
var attribute = el.attributes.getNamedItemNS(namespaceURI, localName)
|
||||||
if attribute != nil:
|
if attribute != nil:
|
||||||
return attribute.value
|
return attribute.value
|
||||||
else:
|
else:
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
proc getAttributeNode*(el: PElement, name: string): PAttr =
|
proc getAttributeNode*(el: PElement, name: string): PAttr =
|
||||||
## Retrieves an attribute node by ``name``
|
## Retrieves an attribute node by ``name``
|
||||||
## To retrieve an attribute node by qualified name and namespace URI, use the `getAttributeNodeNS` method
|
## To retrieve an attribute node by qualified name and namespace URI, use the `getAttributeNodeNS` method
|
||||||
|
if el.attributes == nil:
|
||||||
|
return nil
|
||||||
return el.attributes.getNamedItem(name)
|
return el.attributes.getNamedItem(name)
|
||||||
|
|
||||||
proc getAttributeNodeNS*(el: PElement, namespaceURI: string, localName: string): PAttr =
|
proc getAttributeNodeNS*(el: PElement, namespaceURI: string, localName: string): PAttr =
|
||||||
## Retrieves an `Attr` node by ``localName`` and ``namespaceURI``
|
## Retrieves an `Attr` node by ``localName`` and ``namespaceURI``
|
||||||
|
if el.attributes == nil:
|
||||||
|
return nil
|
||||||
return el.attributes.getNamedItemNS(namespaceURI, localName)
|
return el.attributes.getNamedItemNS(namespaceURI, localName)
|
||||||
|
|
||||||
proc getElementsByTagName*(el: PElement, name: string): seq[PNode] =
|
proc getElementsByTagName*(el: PElement, name: string): seq[PNode] =
|
||||||
|
|
@ -909,103 +928,110 @@ proc getElementsByTagNameNS*(el: PElement, namespaceURI: string, localName: stri
|
||||||
result = el.findNodesNS(namespaceURI, localName)
|
result = el.findNodesNS(namespaceURI, localName)
|
||||||
|
|
||||||
proc hasAttribute*(el: PElement, name: string): bool =
|
proc hasAttribute*(el: PElement, name: string): bool =
|
||||||
## Returns ``true`` when an attribute with a given ``name`` is specified
|
## Returns ``true`` when an attribute with a given ``name`` is specified
|
||||||
## on this element , ``false`` otherwise.
|
## on this element , ``false`` otherwise.
|
||||||
|
if el.attributes == nil:
|
||||||
|
return false
|
||||||
return el.attributes.getNamedItem(name) != nil
|
return el.attributes.getNamedItem(name) != nil
|
||||||
|
|
||||||
proc hasAttributeNS*(el: PElement, namespaceURI: string, localName: string): bool =
|
proc hasAttributeNS*(el: PElement, namespaceURI: string, localName: string): bool =
|
||||||
## Returns ``true`` when an attribute with a given ``localName`` and
|
## Returns ``true`` when an attribute with a given ``localName`` and
|
||||||
## ``namespaceURI`` is specified on this element , ``false`` otherwise
|
## ``namespaceURI`` is specified on this element , ``false`` otherwise
|
||||||
|
if el.attributes == nil:
|
||||||
|
return false
|
||||||
return el.attributes.getNamedItemNS(namespaceURI, localName) != nil
|
return el.attributes.getNamedItemNS(namespaceURI, localName) != nil
|
||||||
|
|
||||||
proc removeAttribute*(el: PElement, name: string) =
|
proc removeAttribute*(el: PElement, name: string) =
|
||||||
## Removes an attribute by ``name``
|
## Removes an attribute by ``name``
|
||||||
for i in low(el.attributes)..high(el.attributes):
|
if el.attributes != nil:
|
||||||
if el.attributes[i].FName == name:
|
for i in low(el.attributes)..high(el.attributes):
|
||||||
el.attributes.delete(i)
|
if el.attributes[i].FName == name:
|
||||||
|
el.attributes.delete(i)
|
||||||
|
|
||||||
proc removeAttributeNS*(el: PElement, namespaceURI: string, localName: string) =
|
proc removeAttributeNS*(el: PElement, namespaceURI: string, localName: string) =
|
||||||
## Removes an attribute by ``localName`` and ``namespaceURI``
|
## Removes an attribute by ``localName`` and ``namespaceURI``
|
||||||
for i in low(el.attributes)..high(el.attributes):
|
if el.attributes != nil:
|
||||||
if el.attributes[i].FNamespaceURI == namespaceURI and
|
for i in low(el.attributes)..high(el.attributes):
|
||||||
el.attributes[i].FLocalName == localName:
|
if el.attributes[i].FNamespaceURI == namespaceURI and
|
||||||
el.attributes.delete(i)
|
el.attributes[i].FLocalName == localName:
|
||||||
|
el.attributes.delete(i)
|
||||||
|
|
||||||
proc removeAttributeNode*(el: PElement, oldAttr: PAttr): PAttr =
|
proc removeAttributeNode*(el: PElement, oldAttr: PAttr): PAttr =
|
||||||
## Removes the specified attribute node
|
## Removes the specified attribute node
|
||||||
## If the attribute node cannot be found raises ``ENotFoundErr``
|
## If the attribute node cannot be found raises ``ENotFoundErr``
|
||||||
for i in low(el.attributes)..high(el.attributes):
|
if el.attributes != nil:
|
||||||
if el.attributes[i] == oldAttr:
|
for i in low(el.attributes)..high(el.attributes):
|
||||||
result = el.attributes[i]
|
if el.attributes[i] == oldAttr:
|
||||||
el.attributes.delete(i)
|
result = el.attributes[i]
|
||||||
return result
|
el.attributes.delete(i)
|
||||||
|
return result
|
||||||
|
|
||||||
raise newException(ENotFoundErr, "oldAttr is not a member of el's Attributes")
|
raise newException(ENotFoundErr, "oldAttr is not a member of el's Attributes")
|
||||||
|
|
||||||
proc setAttributeNode*(el: PElement, newAttr: PAttr): PAttr =
|
proc setAttributeNode*(el: PElement, newAttr: PAttr): PAttr =
|
||||||
## Adds a new attribute node, if an attribute with the same `nodeName` is
|
## Adds a new attribute node, if an attribute with the same `nodeName` is
|
||||||
## present, it is replaced by the new one and the replaced attribute is
|
## present, it is replaced by the new one and the replaced attribute is
|
||||||
## returned, otherwise ``nil`` is returned.
|
## returned, otherwise ``nil`` is returned.
|
||||||
|
|
||||||
# Check if newAttr is from this nodes document
|
# Check if newAttr is from this nodes document
|
||||||
if el.FOwnerDocument != newAttr.FOwnerDocument:
|
if el.FOwnerDocument != newAttr.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr,
|
raise newException(EWrongDocumentErr,
|
||||||
"This node belongs to a different document, use importNode.")
|
"This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
if newAttr.FOwnerElement != nil:
|
if newAttr.FOwnerElement != nil:
|
||||||
raise newException(EInuseAttributeErr,
|
raise newException(EInuseAttributeErr,
|
||||||
"This attribute is in use by another element, use cloneNode")
|
"This attribute is in use by another element, use cloneNode")
|
||||||
# Exceptions end
|
# Exceptions end
|
||||||
|
|
||||||
if isNil(el.attributes): el.attributes = @[]
|
if el.attributes == nil: el.attributes = @[]
|
||||||
return el.attributes.setNamedItem(newAttr)
|
return el.attributes.setNamedItem(newAttr)
|
||||||
|
|
||||||
proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr =
|
proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr =
|
||||||
## Adds a new attribute node, if an attribute with the localName and
|
## Adds a new attribute node, if an attribute with the localName and
|
||||||
## namespaceURI of ``newAttr`` is present, it is replaced by the new one
|
## namespaceURI of ``newAttr`` is present, it is replaced by the new one
|
||||||
## and the replaced attribute is returned, otherwise ``nil`` is returned.
|
## and the replaced attribute is returned, otherwise ``nil`` is returned.
|
||||||
|
|
||||||
# Check if newAttr is from this nodes document
|
# Check if newAttr is from this nodes document
|
||||||
if el.FOwnerDocument != newAttr.FOwnerDocument:
|
if el.FOwnerDocument != newAttr.FOwnerDocument:
|
||||||
raise newException(EWrongDocumentErr,
|
raise newException(EWrongDocumentErr,
|
||||||
"This node belongs to a different document, use importNode.")
|
"This node belongs to a different document, use importNode.")
|
||||||
|
|
||||||
if newAttr.FOwnerElement != nil:
|
if newAttr.FOwnerElement != nil:
|
||||||
raise newException(EInuseAttributeErr,
|
raise newException(EInuseAttributeErr,
|
||||||
"This attribute is in use by another element, use cloneNode")
|
"This attribute is in use by another element, use cloneNode")
|
||||||
# Exceptions end
|
# Exceptions end
|
||||||
|
|
||||||
if isNil(el.attributes): el.attributes = @[]
|
if el.attributes == nil: el.attributes = @[]
|
||||||
return el.attributes.setNamedItemNS(newAttr)
|
return el.attributes.setNamedItemNS(newAttr)
|
||||||
|
|
||||||
proc setAttribute*(el: PElement, name: string, value: string) =
|
proc setAttribute*(el: PElement, name: string, value: string) =
|
||||||
## Adds a new attribute, as specified by ``name`` and ``value``
|
## Adds a new attribute, as specified by ``name`` and ``value``
|
||||||
## If an attribute with that name is already present in the element, its
|
## If an attribute with that name is already present in the element, its
|
||||||
## value is changed to be that of the value parameter
|
## value is changed to be that of the value parameter
|
||||||
## Raises the EInvalidCharacterErr if the specified ``name`` contains
|
## Raises the EInvalidCharacterErr if the specified ``name`` contains
|
||||||
## illegal characters
|
## illegal characters
|
||||||
var AttrNode = el.FOwnerDocument.createAttribute(name)
|
var AttrNode = el.FOwnerDocument.createAttribute(name)
|
||||||
# Check if name contains illegal characters
|
# Check if name contains illegal characters
|
||||||
if illegalChars in name:
|
if illegalChars in name:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
||||||
discard el.setAttributeNode(AttrNode)
|
discard el.setAttributeNode(AttrNode)
|
||||||
# Set the info later, the setAttributeNode checks
|
# Set the info later, the setAttributeNode checks
|
||||||
# if FOwnerElement is nil, and if it isn't it raises an exception
|
# if FOwnerElement is nil, and if it isn't it raises an exception
|
||||||
AttrNode.FOwnerElement = el
|
AttrNode.FOwnerElement = el
|
||||||
AttrNode.FSpecified = True
|
AttrNode.FSpecified = True
|
||||||
AttrNode.value = value
|
AttrNode.value = value
|
||||||
|
|
||||||
proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) =
|
proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) =
|
||||||
## Adds a new attribute, as specified by ``namespaceURI``, ``localName``
|
## Adds a new attribute, as specified by ``namespaceURI``, ``localName``
|
||||||
## and ``value``.
|
## and ``value``.
|
||||||
|
|
||||||
# Check if name contains illegal characters
|
# Check if name contains illegal characters
|
||||||
if illegalChars in namespaceURI or illegalChars in localName:
|
if illegalChars in namespaceURI or illegalChars in localName:
|
||||||
raise newException(EInvalidCharacterErr, "Invalid character")
|
raise newException(EInvalidCharacterErr, "Invalid character")
|
||||||
|
|
||||||
var AttrNode = el.FOwnerDocument.createAttributeNS(namespaceURI, localName)
|
var AttrNode = el.FOwnerDocument.createAttributeNS(namespaceURI, localName)
|
||||||
|
|
||||||
discard el.setAttributeNodeNS(AttrNode)
|
discard el.setAttributeNodeNS(AttrNode)
|
||||||
# Set the info later, the setAttributeNode checks
|
# Set the info later, the setAttributeNode checks
|
||||||
# if FOwnerElement is nil, and if it isn't it raises an exception
|
# if FOwnerElement is nil, and if it isn't it raises an exception
|
||||||
|
|
@ -1013,19 +1039,19 @@ proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) =
|
||||||
AttrNode.FSpecified = True
|
AttrNode.FSpecified = True
|
||||||
AttrNode.value = value
|
AttrNode.value = value
|
||||||
|
|
||||||
# Text
|
# Text
|
||||||
proc splitData*(TextNode: PText, offset: int): PText =
|
proc splitData*(TextNode: PText, offset: int): PText =
|
||||||
## Breaks this node into two nodes at the specified offset,
|
## Breaks this node into two nodes at the specified offset,
|
||||||
## keeping both in the tree as siblings.
|
## keeping both in the tree as siblings.
|
||||||
|
|
||||||
if offset > TextNode.data.len():
|
if offset > TextNode.data.len():
|
||||||
raise newException(EIndexSizeErr, "Index out of bounds")
|
raise newException(EIndexSizeErr, "Index out of bounds")
|
||||||
|
|
||||||
var left: string = TextNode.data.substr(0, offset)
|
var left: string = TextNode.data.substr(0, offset)
|
||||||
TextNode.data = left
|
TextNode.data = left
|
||||||
var right: string = TextNode.data.substr(offset, TextNode.data.len())
|
var right: string = TextNode.data.substr(offset, TextNode.data.len())
|
||||||
|
|
||||||
if TextNode.FParentNode != nil:
|
if TextNode.FParentNode != nil and TextNode.FParentNode.childNodes != nil:
|
||||||
for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes):
|
for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes):
|
||||||
if TextNode.FParentNode.childNodes[i] == TextNode:
|
if TextNode.FParentNode.childNodes[i] == TextNode:
|
||||||
var newNode: PText = TextNode.FOwnerDocument.createTextNode(right)
|
var newNode: PText = TextNode.FOwnerDocument.createTextNode(right)
|
||||||
|
|
@ -1042,10 +1068,10 @@ proc target*(PI: PProcessingInstruction): string =
|
||||||
|
|
||||||
return PI.FTarget
|
return PI.FTarget
|
||||||
|
|
||||||
|
|
||||||
# --Other stuff--
|
# --Other stuff--
|
||||||
# Writer
|
# Writer
|
||||||
proc addEscaped(s: string): string =
|
proc addEscaped(s: string): string =
|
||||||
result = ""
|
result = ""
|
||||||
for c in items(s):
|
for c in items(s):
|
||||||
case c
|
case c
|
||||||
|
|
@ -1057,10 +1083,11 @@ proc addEscaped(s: string): string =
|
||||||
|
|
||||||
proc nodeToXml(n: PNode, indent: int = 0): string =
|
proc nodeToXml(n: PNode, indent: int = 0): string =
|
||||||
result = repeatChar(indent, ' ') & "<" & n.nodeName
|
result = repeatChar(indent, ' ') & "<" & n.nodeName
|
||||||
for i in items(n.Attributes):
|
if n.attributes != nil:
|
||||||
result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"")
|
for i in items(n.attributes):
|
||||||
|
result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"")
|
||||||
if n.childNodes.len() == 0:
|
|
||||||
|
if n.childNodes == nil or n.childNodes.len() == 0:
|
||||||
result.add("/>") # No idea why this doesn't need a \n :O
|
result.add("/>") # No idea why this doesn't need a \n :O
|
||||||
else:
|
else:
|
||||||
# End the beginning of this tag
|
# End the beginning of this tag
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue