Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A simple Tdom problem...

313 views
Skip to first unread message

WJG

unread,
Aug 9, 2019, 7:14:46 AM8/9/19
to
I have a simple XML file which I'm parsing in tdom and looking to retrieve node-ids using the xpath. But, I'm running into issues. I may have overlooked something simple here, any advice welcome. The version of tdom installed is 0.8.3-1

The following works fine..

set xml {
<office:document>
<office:meta/>
<office:settings/>
<office:script/>
<office:font-face-decls/>
<office:styles/>
<office:automatic-styles/>
<office:body>
<office:text/>
</office:body>
</office:document>
}

# valid XML, works...
set doc [dom parse $xml]

# this works...
set root [$doc documentElement]

# this too, lists the nodes...
foreach n [$root childNodes] { puts >[$n nodeName]< }


But, the following line...


set node [$root selectNodes /office:document/office:body]


..comes up with the error...


Prefix doesn't resolve
while executing
"$root selectNodes /office:document/office:body"
invoked from within
"set node [$root selectNodes /office:document/office:body]"


Any advice most welcome.

WJG


Rich

unread,
Aug 9, 2019, 7:43:56 AM8/9/19
to
That XML file uses XML namespaces (the "office:" prefix is an XML
namespace). You need to setup a map using either the "-namespaces
prefixUriList" option to selectNodes, or a global
"selectNodesNamespaces" map on the document element to get selectNodes
to always work correctly.

Unfortunately, for us to show what to put in that map, we likely [1] need
to see the document root element to know what the long form name is for
the "office:" within the document prefix.

[1] It is possible to have sub-tree specific namespaces, but those are
seldom used, usually the document global definition applies (the ones
on the root element).

Rolf Ade

unread,
Aug 9, 2019, 9:51:20 AM8/9/19
to

WJG <wjgid...@googlemail.com> writes:
> I have a simple XML file which I'm parsing in tdom and looking to
> retrieve node-ids using the xpath. But, I'm running into issues. I may
> have overlooked something simple here, any advice welcome. The version
> of tdom installed is 0.8.3-1

You'd better use 0.9.1 (released July 2018, more than a year ago).

> The following works fine..
>
> set xml {
> <office:document>
> <office:meta/>
> <office:settings/>
> <office:script/>
> <office:font-face-decls/>
> <office:styles/>
> <office:automatic-styles/>
> <office:body>
> <office:text/>
> </office:body>
> </office:document>
> }
>
> # valid XML, works...
> set doc [dom parse $xml]

[Just a terminology note, I think I got what you mean: ym well-formed.
Valid in XML speech means the XML conforms to some schema.]

Well, actually ... depends. And for your use case: no.

See, there are two different types of XML.

XML, as specified by the w3c XML recommendation, doesn't know anything
about XML namespaces. This spec allows xml the colon as a name character
inside element names (not as start character).

Nowadays, most people expect an XML document to follow the w3c XML _and_
the w3c XML Namespaces recommendation (without explicitly saying so).[1]

Your example document is well-formed according to the XML
recommendation. But it is not according to the rules of the XML and the
XML Namespaces recommendation.

Since you want to use XPath expressions (this is, what you do, if you
use the selectNodes method) and since XPath is per recommendation an XML
Namespaces aware query language you need a document which is well-formed
according to the XML as well as the XML Namespaces recommendation, if
you want to use this with success.

So, correct your input and this should start to work. E.g.:

set xml {
<office:document xmlns:office="the_office_namespace_uri">
<office:meta/>
<office:settings/>
<office:script/>
<office:font-face-decls/>
<office:styles/>
<office:automatic-styles/>
<office:body>
<office:text/>
</office:body>
</office:document>
}

> # this works...
> set root [$doc documentElement]
>
> # this too, lists the nodes...
> foreach n [$root childNodes] { puts >[$n nodeName]< }

Yes. This methods are XML namespace agnostic and work on both types of
XML (in a probably "expected" way).

> But, the following line...
>
> set node [$root selectNodes /office:document/office:body]
>
> ..comes up with the error...
>
> Prefix doesn't resolve
> while executing
> "$root selectNodes /office:document/office:body"
> invoked from within
> "set node [$root selectNodes /office:document/office:body]"

Sure. XPath is XML namespace aware. That means, if tDOMs XPath parser
sees something looking like a XML namespace prefix in the XPath
expression it expects that prefix to be bound to an XML namespace. Which
isn't with your original input.

BTW: It won't help, to bind your prefix to a namespace URI with $doc
selectNodesNamespaces or the -namespaces {prefix URI ...} option of the
selectNodes method, as another poster mentioned.

With that the prefix will resolve (and the XPath parser doesn't raise
error anymore) but you still don't get the result you want. The engine
will search for nodes in that namespace, but since the nodes of your
original XML input are not in any namespace after parsing, the call will
return an empty node set.

rolf

1) Because of this newer (than 0.8.3) versions of tDOM by default expect
XML input to be compliant to both the XML and the XML Namespaces
recommendation. So, with a more recent tDOM your

set doc [dom parse $xml]

will already raise the error:

Namespace prefix is not defined, referenced at line 2 character 18

If you really want to parse XML input conforming (only) to the XML but
not the XML Namespaces recommendation use the -ignorexmlns option of the
parse method. But be warned: you will have all kinds of problems to
select any prefixed element directly with selectNodes/XPath.

Rolf Ade

unread,
Aug 9, 2019, 9:55:28 AM8/9/19
to
I'm afraid, that won't help; see my other posting in this thread for the
explanation.

rolf

WJG

unread,
Aug 9, 2019, 10:56:53 AM8/9/19
to
Hi Rolf, Rich

Thanks for this tips. I've update my copy of tdom to 0.9.1 as you've both suggested (I still need to read them again a few times to get the full benefit) and my code is running nicely.

I'm currently putting some final touches to an fodt export package which has not been without its frustrations, the least of which was to make the node building process humanly readable!

Now that I've sussed out how to make the basic document tree and assign nodes to package wide variables I can streamline the addition and creation of my existing proc for the styles, paragraphs, tables, etc and all the other gubbins that go into the sprawling heap of markup that is a WP file.

'He who dares wins, eh?'


Have a great weekend.

Will

Rich

unread,
Aug 9, 2019, 11:12:50 AM8/9/19
to
Yes, just saw your explanation. I was unaware of that additional
complication surrounding xml namespaces.

Rolf Ade

unread,
Aug 9, 2019, 11:28:40 AM8/9/19
to

WJG <wjgid...@googlemail.com> writes:
> Thanks for this tips. I've update my copy of tdom to 0.9.1 as you've
> both suggested (I still need to read them again a few times to get the
> full benefit) and my code is running nicely.

Fine.

> I'm currently putting some final touches to an fodt export package
> which has not been without its frustrations, the least of which was to
> make the node building process humanly readable!
>
> Now that I've sussed out how to make the basic document tree and
> assign nodes to package wide variables I can streamline the addition
> and creation of my existing proc for the styles, paragraphs, tables,
> etc and all the other gubbins that go into the sprawling heap of
> markup that is a WP file.

What kind of OpenDocument documents are you aim to write? (From your
description and your former XML example I suspect you want to create
OpenDocument documents with Tcl.) Do you plan to publish the code?

It may be interesting to you what ooxml[1] does. This packages (also
using tDOM) creates .xlsx files (vulog Excel sheets) from Tcl.

rolf

1) https://tcl.sowaswie.de/repos/fossil/ooxml/home

WJG

unread,
Aug 9, 2019, 12:56:46 PM8/9/19
to
Hi Rolf,

I already have an earlier version running based upon string splicing which works ok, but I wanted to improve on this. The code is used in a project of mine which is a computer aided translation environment that offers the ability to save completed jobs out in a variety of formats using LibreOffice as the conversion engine. My earlier version makes straight zip compressed odt files by appending strings of XML snippets but it takes a lot of fiddling, so fodt offers a less frustrating approach. Besides, I wanted to learn Tdom while offering more control over document formatting. This project is already opensource.
I'll take a lookt at ooxml it may offer some good ideas.

Will

Rich

unread,
Aug 9, 2019, 2:06:36 PM8/9/19
to
WJG <wjgid...@googlemail.com> wrote:
> ... My earlier version makes straight zip compressed odt files by
> appending strings of XML snippets ...

This is an extremely fiddly (as you have discovered) and very fragile
way to assemble XML documents.

There are so many 'quirks' in regards to XML structure and escaping and
such that it is *very* easy to get something wrong by going with the
'appending strings' approach.

Using tDom to do the assembly, you can simply supply the data or
attribute names and values you want, and leave the low level XML format
fiddlings to tDom to handle. Doing so will make things *much* easier
to get right, and make your code much cleaner overall.

WJG

unread,
Aug 9, 2019, 4:56:21 PM8/9/19
to

Hi Rolf,

Thanks for the good advice. I read the Tdom tutorial and followed this approach, but then appending worked too and I could quickly add snippets rather than the laborious task of working through massive lists of attributes. It all worked in 0.8.3 but throws errors in 0.9.1.

Here's a brief script, adding an office:text child node to office:body it crashes throwing a 'parsing aborted' error, is there a workaround.

At this point I'm serious thinking of mapping office: to office_ build the whole tree and then swap it back before saving.


set xml {
<office:document
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rpt="http://openoffice.org/2005/report"
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:grddl="http://www.w3.org/2003/g/data-view#"
xmlns:officeooo="http://openoffice.org/2009/office"
xmlns:tableooo="http://openoffice.org/2009/table"
xmlns:drawooo="http://openoffice.org/2010/draw"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
xmlns:css3t="http://www.w3.org/TR/css3-text/"
office:version="1.2"
office:mimetype="application/vnd.oasis.opendocument.text">
<office:settings/>
<office:meta/>
<office:script/>
<office:font-face-decls/>
<office:styles/>
<office:automatic-styles/>
<office:body>
<office:text/>
</office:body>
</office:document>
}

# valid XML
set doc [dom parse $xml]

# this works...
set root [$doc documentElement]
set node [$root selectNodes /office:document/office:body]

# this works...
$node appendChild [$doc createElement office:text]

# but this doesn't, why?
$node appendXML {<office:text/>}


Crashes, giving:

error "parsing aborted" at line 1 character 14
"<office:text/>"
while executing
"$node appendXML {<office:text/>} "
(procedure "main" line 72)
invoked from within
"main"
(file "test-tdom-parse.tcl" line 167)


Rolf Ade

unread,
Aug 9, 2019, 8:20:00 PM8/9/19
to

WJG <wjgid...@googlemail.com> writes:
> Thanks for the good advice. I read the Tdom tutorial and followed this

What resources is this to which you refer with "Tdom tutorial"?

> approach, but then appending worked too and I could quickly add
> snippets rather than the laborious task of working through massive
> lists of attributes. It all worked in 0.8.3 but throws errors in
> 0.9.1.
>
> Here's a brief script, adding an office:text child node to office:body
> it crashes throwing a 'parsing aborted' error, is there a workaround.
> [...]
Well, well-formed.

> # this works...
> set root [$doc documentElement]
> set node [$root selectNodes /office:document/office:body]
>
> # this works...
> $node appendChild [$doc createElement office:text]

This (createElement, I mean) is DOM I, XML rec only, XML namespace
agnostic, creating only elements in no namespace. This may (since you
generate just for export you may be fine, it serializes to what you
expect) or may not what you want.

> # but this doesn't, why?
> $node appendXML {<office:text/>}

The same thing, as with your first posting, no? This isn't well-formed
according to the XML Namespaces recommendation? Try for example:

$node appendXML {<office:text xmlsn="office"/>}

You can only feed well-formed XML to the appendXML. Everything that
parses with [dom parse $xml]

Rolf Ade

unread,
Aug 9, 2019, 8:57:36 PM8/9/19
to

WJG <wjgid...@googlemail.com> writes:
> I already have an earlier version running based upon string splicing
> which works ok, but I wanted to improve on this. The code is used in a
> project of mine which is a computer aided translation environment that
> offers the ability to save completed jobs out in a variety of formats
> using LibreOffice as the conversion engine. My earlier version makes
> straight zip compressed odt files by appending strings of XML snippets
> but it takes a lot of fiddling, so fodt offers a less frustrating
> approach.

For generating zipped office documents I used in a project an extension
to zipfile::mkzip (for the core see http://paste.tclers.tk/4807) and
ooxml uses vfs::zip. Both works well.

> Besides, I wanted to learn Tdom while offering more control
> over document formatting. This project is already opensource.

Could you please provide a link to that?

tDOM offers some, that could help you. The probably most important point
is that you consider, if the appendFromScript (et. al.) way of building
up (sub-) trees from scratch may offer you something for your task.

As mentioned, for a project I implemend output to execl (because of some
MS extension for defining drop-down cells, with values in the drop-down
selection from an cell range on another sheet the target was explicitly
Excel, though e.g. libreoffice opens the output well, just without that
drow-down thingy) and build up the various XML files defining an
OpenDocument with tDOM.

Unfortunately I can't publish this not only because it's customers code
but also because it is somewhat ad-hoc and has a specialized, not
necessary generic useful API.

With this, I generate, to give a modest number, 100000 cells per
seconds. Which is not earth-shaking (a document with 100000+ rows and a
some columns will still take several seconds), but also not so bad.

> I'll take a lookt at ooxml it may offer some good ideas.

I found it because the author and maintainer asked me about tDOM and I
see it with some hope. It's already usable, for some tasks (and it has a
sexy showcase: export your tabellist to an .xlsx with just a few lines
of code).

It has a few miles to go, in some respects but some of its basic
approaches are a good example skeleton for what to do if one want to
generate other types of OpenDocuments with the help of tDOM.

rolf

Rolf Ade

unread,
Aug 9, 2019, 9:10:51 PM8/9/19
to


Rolf Ade <ro...@pointsman.de> writes:
> $node appendXML {<office:text xmlsn="office"/>}

Please excuse, this is wrong. I obviously meant to write:

$node appendXML {<office:text xmlsn:office="the_office_url"/>}

WJG

unread,
Aug 12, 2019, 4:10:03 AM8/12/19
to
Hi Rolf,


> > $node appendXML {<office:text xmlsn="office"/>}
>
> Please excuse, this is wrong. I obviously meant to write:
>
> $node appendXML {<office:text xmlsn:office="the_office_url"/>}

Whilst this allows tdom to add the node, when the resulting xml file is loaded into LibreOffice it comes up as an error. Besides, every node in am odt/fpodt file is located in one xml namespace or another which makes this approach problematic. Pity that its possible to parse a complete xml file but not append xml segments.

It looks like I'll have to settle with using tdom 0.8.3, unless there's a little use option somewhere in 0.9.1 that will help.

Will

Rolf Ade

unread,
Aug 12, 2019, 6:31:04 AM8/12/19
to

WJG <wjgid...@googlemail.com> writes:
>> Please excuse, this is wrong. I obviously meant to write:
>>
>> $node appendXML {<office:text xmlsn:office="the_office_url"/>}
^^

Shouldn't post late in the night; you've spotted my typo in the (meant
to be the) corrected version?

In another part of this thread we had this conversation:

Rolf Ade <ro...@pointsman.de> writes:
> WJG <wjgid...@googlemail.com> writes:
>> [...]
>> Besides, I wanted to learn Tdom while offering more control
>> over document formatting. This project is already opensource.
>
> Could you please provide a link to that?

Lemme ask again for a link to you work. Not just for curiosity but to
get a both broader and more precise picture of what you try to do. Which
may enable us here to give better adivce / explanations.

> Whilst this allows tdom to add the node, when the resulting xml file
> is loaded into LibreOffice it comes up as an error. Besides, every
> node in am odt/fpodt file is located in one xml namespace or another
> which makes this approach problematic. Pity that its possible to parse
> a complete xml file but not append xml segments.

This is somewhat contradictory. In the first line of that paragraph you
confirm that you are able to do what you call in the last sentence a
pity that you can't.

You just report "no sucess" without other detail and since my crystal
ball is a bit cloudy at the moment I'm afraid I can't offer much help.

Other than, maybe, a truism: Using a fancy vector graphics editor (even
the most top-notch available) doesn't make magically a fine graphics
artist out of you, I you aren't. A tool offers help but knowing the
field is indispensable to some degree. That surely is also true while
working with XML. Cargo cult copying code snippets only goes so far.

At least be assured what you try to do is possible. There's prior art,
not only by me but also (independent from me) by others.

> It looks like I'll have to settle with using tdom 0.8.3, unless
> there's a little use option somewhere in 0.9.1 that will help.

I can't advice to stick with that older version. But it's your project
and task; whatever works for you is probably sufficient.

About "a little use option" in 0.9.1 - my crystal ball is still too
cloudy ...

rolf

WJG

unread,
Aug 12, 2019, 4:26:31 PM8/12/19
to
Hi Rolf,

Again, thanks for the comments on the XML side (except for the 'cargo cult' comment which is tad a pejorative).

I've now managed to get a satisfactory workaround for appending nodes with xmlns tags. Not done according to the rule book, but realized what I needed to achieve - to use pango markup in my text nodes.

I'll upload the package and a couple of demo scripts to Sourceforge and add the link in my next post. Perhaps you'd care to critique it when ready.

WJG

WJG

unread,
Aug 12, 2019, 4:35:45 PM8/12/19
to
Just uploaded a few files to https://sourceforge.net/projects/odtexport/

stefan

unread,
Aug 12, 2019, 6:11:13 PM8/12/19
to
Hi William!

> Again, thanks for the comments on the XML side (except for the 'cargo cult' comment which is tad a pejorative).

I agree, not the appropriate tone but Rolf is nevertheless right in saying that

> A tool offers help but knowing the
> field is indispensable to some degree.

I looked at your "odtExport.tcl", especially "addNode":

proc odt::addNode { parent name {args {} } } {

set ::node::doc [dom createDocument $name]
set newNode [$::node::doc documentElement]
$parent appendChild $newNode

if { $args != ""} { foreach {a b} {*}$args { $newNode setAttribute $a $b } }

return $newNode
}

This reveals what Rolf felt in his guts, some fundamental misunderstandings regarding XML, XML namespaces, and DOM at your end. Even a workaround should not create separate documents (createDocument) for each element you wish to add. What you are creating is not namespace-aware (neither the documents, nor the elements). You seem to replicate your string-assembly (concrete syntax) approach using the tDOM API, rather than assembling a namespace-aware XML document (abstract syntax).

Let's re-start from here, after having parsed the minimal OpenDocument content:

% set body [$root selectNodes /office:document/office:body]
domNode0x7fa08d003590
% $body asXML
<office:body>
<office:text/>
</office:body>

To cut things short, you want to use the namespace-aware tDOM, e.g., "createElementNS". You always have to proceed in two steps: create an element (in the intended NS), then inject it into the document structure.

% $body appendChild [$doc createElementNS urn:oasis:names:tc:opendocument:xmlns:office:1.0 office:text]
domNode0x7fa089e0db60
% $body asXML
<office:body>
<office:text/>
<office:text/>
</office:body>

Note, you have to provide an NS (URI) binding (first argument to createElementNS) as well as a namespace-prefix for the new document element ("office:text", not just "text"). Anything other than that will fail you in a number of ways. Just try it:

% $body appendChild [$doc createElement office:text]
domNode0x7fa089d00760
% $body asXML
<office:body>
<office:text/>
<office:text/>
<office:text/>
</office:body>

The namespace-unaware API ("createElement") will only seemingly add a new OASIS text element, it will only do on the surface (concrete syntax). You can verify yourself using XPath:

% $doc selectNodes -namespaces {x urn:oasis:names:tc:opendocument:xmlns:office:1.0} {//x:text}
domNode0x7fa08d003610 domNode0x7fa089e0db60

Shouldn't that be three results? Well, no, the most recently added text element only bears the namespace-prefix "office" (concrete syntax), but is not bound to the namespace "urn:oasis:names:tc:opendocument:xmlns:office:1.0" (abstract syntax).

Consider another alternative: Just omit the namespace prefix "office", just use "text" as tag name:

% $body appendChild [$doc createElementNS urn:oasis:names:tc:opendocument:xmlns:office:1.0 text]
domNode0x7fa08d0018e0
% $body asXML
<office:body>
<office:text/>
<office:text/>
<office:text/>
<text xmlns="urn:oasis:names:tc:opendocument:xmlns:office:1.0"/>
</office:body>

This will create a text element, that, at the concrete-syntax level looks different than the others (it is bound to the intended NS using a per-element default NS), but semantically (abstract syntax) it is equivalent to the first two:

% $doc selectNodes -namespaces {x urn:oasis:names:tc:opendocument:xmlns:office:1.0} {//x:text}
domNode0x7fa08d003610 domNode0x7fa089e0db60 domNode0x7fa08d0018e0

This returns three results, the third element is still not registered under the intended NS. Note that I intentionally used a completely different namespace prefix in the XPath query, just to show that namespace prefixes are merely concrete-syntax issues, they do not affect the abstract syntax (namespace bindings).

When this is about serialising (marshalling) some document into an OpenDocument structure, your concrete-syntax approach (besides the smell of excessive document creation and other stylistic details) gets you far, but it is easy to do it just right also at the semantic level. Then, tDOM can help you in avoiding many pitfalls (e.g., using "selectNodes" to navigate the actual structure, not just some syntactic facade).

HTH, Stefan

Rolf Ade

unread,
Aug 12, 2019, 7:05:42 PM8/12/19
to


WJG <wjgid...@googlemail.com> writes:
> Again, thanks for the comments on the XML side (except for the 'cargo
> cult' comment which is tad a pejorative).

I didn't want to sound offensive, sorry. English is a foreign language
to me (which shows), so I may come over with a not intended tone.
(Thought, I sound like an old, boring teacher, telling stories from
war, with that.)

> I've now managed to get a satisfactory workaround for appending nodes
> with xmlns tags. Not done according to the rule book, but realized
> what I needed to achieve - to use pango markup in my text nodes.
>
> I'll upload the package and a couple of demo scripts to Sourceforge
> and add the link in my next post. Perhaps you'd care to critique it
> when ready.

Both demos run for me without any fuss and generate two well looking
.odt files.

From glancing over the code ...

Instead of

proc odt::rootAttributes {} {

odt::setNodeAttributes $::node::root {
xmlns:office "urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style "urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text "urn:oasis:names:tc:opendocument:xmlns:text:1.0"
...


try

proc odt::rootAttributes {} {

$::node::root setAttribute {*}{
xmlns:office "urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style "urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text "urn:oasis:names:tc:opendocument:xmlns:text:1.0"
...

You'll loose tons of documents odt::addNode. After you've moved the
documentElement from your freshly created doc to your tree, the
documentNode still is around and never cleaned up.

There's not reason I'm aware to create new nodes this way in general.
Just use [[$parent ownerDocument] createElement $name].

In general: At a lot of places I would probably use appendFromScript.

And then there is odt::markup ...

Well, you will be able to build up (and use as internal data structure
while build it up successively on a higher user level with selectNodes)
a DOM 2 tree, either use createElementNS or, well, appendFromScript with
rightly created [$doc createNodeCmd ...]s. (You currently don't.)

But there's nothing inherently bad, to build up a DOM 1 tree, which
serialization does looks like a corrent namespaced XML. This can be done
easily (more or less just a piece of work and you've done a great amount
of that already). Just you don't can't do selectNodes naively on that.

So, either use another internal data structure, to store the data, while
it is build up successively, and create the dom tree only at the time,
the result is written (and just serialize it, no needs to do selectNodes
on it.)

Or stick by your architecture (after considering above) and help you out
with XPath expressions like

set ::node::meta [$::node::root selectNodes {
/*[local-name()='document']
/*[local-name()='meta']
}

without need for - how you've called it? - "pango markup". (But I
really don't know, what exactly that mean. What I know: the XPath
expression is guaranteed untested.)

rolf

WJG

unread,
Aug 13, 2019, 7:02:24 PM8/13/19
to
Hi Stefan,

Thanks for comments and advice which I've taken on board and have already used to modfiy both my code and thinking.

In the past I've used tdom to create files for other projects but these were much simpler in comparison to ODT files and no need for namespaces :-)

Still, the rudiments are together and I'm now creating various procs to output the document elements that I want to create under programatic control.

Whenever I've made significant improvements I'll upload the updates up to SourceForge.

Will
0 new messages