Re: failing to read xml

2020-01-08 Thread marks
I found that if I don't go into child nodes then it doesn't assert: but then it 
doesn't go through the XML file either! Here's a modified `write` that still 
asserts: 


proc write(file: File, node: XmlNode, indent: int) =
  if indent > 0:
file.write(spaces(indent))
  file.write(&"<{node.tag}")
  let attrs = node.attrs()
  if attrs != nil:
for (key, value) in attrs.pairs():
  file.write(&" {key}=\"{value}\"")
  file.write(">")
  if node.kind != xnElement and node.text != "":
file.write(node.text)
  if len(node) > 0:
for child in node:
  write(file, child, indent + INDENT)
  file.write(&"\n")


Run

I tried commenting out the attrs code and the node.text code but that didn't 
help.

SOLVED: The problem was with the signature. Even though I don't (knowingly) 
modify any nodes, changing the signature's `node: XmlNode` to `node: var 
XmlNode` cured the assertion error.


Re: failing to read xml

2020-01-08 Thread marks
I modified the `write` proc as suggested but it doesn't help:


if node.kind in {xnText, xnCData, xnEntity, xnComment} and
  node.text != "":
file.write(node.text)


Run

Assert: 


fatal.nim(39)sysFatal
Error: unhandled exception: xmltree.nim(213, 10) `n.k == xnElement`  
[AssertionError]


Run

I also tried:


if node.kind != xnElement and node.text != "":
file.write(node.text)


Run

And that also asserted with the same message.

And just to be sure I then commented out the `if` statement so that I _never_ 
use `node.text`; and it still gives exactly the same assertion.


Re: failing to read xml

2020-01-08 Thread sschwarzer
Every `XMLNode` [has a kind](https://nim-lang.org/docs/xmltree.html#7) and I 
guess the reason you get this error is that you use the `text` field although 
the node isn't a text node. In that case you must check the node kind first: 


if node.kind == xnText and node.text != "":
  ...


Run

Besides, the result of `$node` for the top-level node may already do most if 
not all of what you want. That said, I don't know if `$node` is missing any 
subtle information that would be necessary to reproduce the original XML 
semantically.


Re: failing to read xml

2020-01-08 Thread cdome
check node.kind before reading node.text


failing to read xml

2020-01-08 Thread marks
I'm trying to learn nim's `xmlparser` and `xmltree` modules.

To do this I'm writing a program that will (eventually) pretty-print XML.

But unfortunately, it asserts on every XML file I've tried to run it with. The 
code and the smallest possible XML file I could make that asserts and the 
assert itself are as follows:


# xml2xml.nim
{.experimental: "codeReordering".}

import os
import strformat
import strtabs
import strutils
import xmlparser
import xmltree

const INDENT = 4

main()

proc main() =
  let args = commandLineParams()
  if len(args) == 0 or args[0] in ["/?", "-h", "--help"]:
let appname = lastPathPart(getAppFilename())
quit(&"usage: {appname} file.xml [file2.xml ...]")
  for arg in args:
pretty(arg)

proc pretty(infilename: string) =
  let i = infilename.rfind('.')
  let outfilename = infilename[0 ..< i] & "#.xml"
  var errors = newSeq[string]()
  let root = loadXml(infilename, errors)
  if len(errors) > 0:
for error in errors:
  echo(&"Error: {error}")
  try:
var file = open(outfilename, fmWrite)
defer: file.close()
file.write(xmlHeader)
write(file, root, 0)
  except IOError as err:
echo(&"Failed to write to \"{outfilename}\": {err.msg}")

proc write(file: File, node: XmlNode, indent: int) =
  if indent > 0:
file.write(spaces(indent))
  file.write(&"<{node.tag}")
  let attrs = node.attrs()
  if attrs != nil:
for (key, value) in attrs.pairs():
  file.write(&" {key}=\"{value}\"")
  file.write(">")
  if node.text != "":
file.write(node.text)
  for child in node:
write(file, child, indent + INDENT)
  file.write(&"\n")


Run

The simpletest XML file I could make (`meta.xml`):







Run

The runtime assertion error: 


/home/mark/app/nim/xml2xml/xml2xml.nim(16) xml2xml
/home/mark/app/nim/xml2xml/xml2xml.nim(24) main
/home/mark/app/nim/xml2xml/xml2xml.nim(38) pretty
/home/mark/app/nim/xml2xml/xml2xml.nim(51) write
/home/mark/opt/nim/lib/pure/xmltree.nim(176) text
/home/mark/opt/nim/lib/system/assertions.nim(27) failedAssertImpl
/home/mark/opt/nim/lib/system/assertions.nim(20) raiseAssert
/home/mark/opt/nim/lib/system/fatal.nim(39) sysFatal
Error: unhandled exception: /home/mark/opt/nim/lib/pure/xmltree.nim(176, 
10) `n.k in {xnText, xnComment, xnCData, xnEntity}`  [AssertionError]


Run

The problem could, of course, be with my own code: maybe I don't understand how 
to use `xmltree` and `XmlNode`'s properly yet.