I’m working on a class that creates and works with xml files. After some trouble with namespaces and a bug in Flex that I managed to get around, this is what I’ve got so far (simplified)…
package uk.co.clockedin.test.test1{
public class LibraryData
{
public namespace ns = "http://www.clockedin.co.uk/test1";
private var xmlRoot:XML;
private function constructNewXML():void
{
trace("Constructing new XML object.");
use namespace ns;
xmlRoot =
<xml xmlns='http://www.clockedin.co.uk/test1'>
<library />
<counter nextID='1' />
</xml>;
}
public function insertItem(item:LibraryItem):LibraryItem
{
use namespace ns;
var newItem:XML = <item />;
newItem.@id = getNextId();
newItem.name[0] = item.name;
newItem.description[0] = item.description;
newItem.author[0] = item.author;
libraryRoot.appendChild(newItem);
return item;
}
}
}
Despite many ambiguities and strange ways of having to go about things (default xml namespace doesn’t work in Flex for example), my main problem is with insertItem().
Is it just me, or does this seem very odd? If I specified at the beginning of the code block use namespace ns, why is it not doing so? And what’s all this aaa prefixing?
All I want is to add an item with the above-specified sub-nodes, and inherit the root node’s namespace, namely “http://www.clockedin.co.uk/test1”.
How can I do this and avoid this strange intrinsic namespacing? I’d prefer not to use a hack. I’m sure I’m not alone on this one…
I realise now that my use of use namespace isn’t strictly correct, but it does seem to work in xml too, and I’ve seen a few examples of it used elsewhere, like here.
My reason for using use namespace was as a replacement for the buggy default xml namespace in Flex. I didn’t want to have to specify the namespace in every line of xml code - what’s the point if I’m only working in 1 namespace anyway. Also, using use namespace hasn’t effected the execution of my code at all - shouldn’t it do that, if my code haven’t been declared in that namespace, or does use namespace do that for me?
My main issue, however, is this strange intrinsic adding of namespaces to the new nodes I created on a seperate XML object. All this stuff:
private function constructNewXML():void
{
trace("Constructing new XML object.");
var ns:Namespace = new Namespace("http://www.clockedin.co.uk/test/test1");
xmlRoot =
<xml>
<library />
<counter nextID='1' />
</xml>;
xmlRoot.addNamespace(ns);
}
addNamespace() requires some prefix for the namespace, while setNamespace() doesn’t. i.e.:
first will produce xmlns:[someprefix]=“someURI” (only in case the provided namespace has prefix!).
second will produce xmlns=“someURI”;
Thanks dude, much appreciated - didn’t spot setNamespace(). Will implement it in the morning.
Getting to the original subject of my post ‘XML good practice’ I have a question about how to go about achieving a task in XML.
I wish to add an XML item to my library node. In AS2 I would’ve done this:
[LIST]
[]Created the ‘item’ node seperately.
[]Populate it.
[*]Append it to the ‘library’ node - job done.
[/LIST]
In AS3, creating the ‘item’ seperately as an XML object gets all this namespace stuff added to it, so what’s the best way around this.
Perhaps appending a new node directly into the library xml would get around this. If so, what’s the best way of accessing this newly appended node in order to populate it. There’s no lastChild() method as in the AS2 XML class. Just wondering if there’s a nice quick way that I haven’t discovered yet.
I tried the code you posted and, as expected, it works. Here are the results of the final trace with the code as you wrote it (with slight changes to node names)…
Nice. The problem is, I wish to add sub nodes to the new ‘item’ nodes. It’s not good practice to only use attributes. So I changed the code to this, to create sub nodes…
public function addToLibrary(d:Object, i:int = 1):void
{
var xn:XML = itemTemplate.copy();
for (var entry:String in d) {
xn[entry][0] = d[entry];
}
if(i <= 0) {
libraryRoot.prependChild(xn);
} else if (libraryRoot.*.length() > i ) {
libraryRoot.replace(i, xn);
} else {
libraryRoot.appendChild(xn);
}
}
And I’m still getting this crazy namespace crap! Here’s the final trace…
I didn’t doctor the info this time - this is actually what I got. The xmlns:aaa entries all match the package:classname of the class I’m running.
One good thing I noticed, is that the toXMLString() automatically sets the xmlns of the <library> node the the inherited xmlns value in its parent node, so I must be on the right track…
Again, surely I’m not the only person who gets this. And surely there are more people out there who have overcome the problem.
Look at the place, where you defined variables a,b,c,d … Does it happen to be somewhere after use namespace directive (while variables declaration has no namespace)? or did you declared them as aaa s:Object = {}; Or didn’t you specify any namespace for them at all? ( var s:Object = {}; )? and specified namespace for the function? In all those cases the namespace will be added to the variable’s name.