Copy link to clipboard
Copied
I'm working on a tree navigation that needs to have some data provided in a nested xml format
<node label="California">
<node label="location 1" />
<node label="location 2">
<node label="option 1" />
<node label="option 2" />
</node>
</node>
But the data that I'm getting (and probably can't change) is coming out flat:
<item>
<id>12</id>
<label>California</label>
</item>
<item>
<id>15</id>
<label>location 1</label>
<parent>12</parent>
</item>
<item>
<id>17</id>
<label>location 2</label>
<parent>12</parent>
</item>
<item>
<id>33</id>
<label>option 1</label>
<parent>17</parent>
</item>
<item>
<id>70</id>
<label>loption 2</label>
<parent>17</parent>
</item>
Any suggestions on how to change that data from what I'm supplied to what I need? Is it just a brute force looping through the xml nodes a bunch of times? Or is there a clever way that I'm not seeing?
Copy link to clipboard
Copied
you receive data formatted one way and you want that data re-organized? if yes, what are you asking?
Copy link to clipboard
Copied
Yes. I get the data in the second format and I need to change it into the first format to provide to the tree component.
What would be the best way to go about doing that?
Copy link to clipboard
Copied
i don't see any similarities between the two xmls but i assume there's some logic that will allow you create a 2nd xml formatted the way you want using the data in the received xml. so, after receiving the flat xml, create a new xml with actionscript and assemble it using that logic.
Copy link to clipboard
Copied
If you are sure about data integrity, especially ids relationships, the following is one of the ways to reposition nodes without changing general node structure. Following this logic you can restructure XML altogether.
With that said, I am not sure XML restructuring is the best way to go anyway. I feel a much better solution would be to parse XML into a more native to AS3 structure like Array, Object or Vector. I would rather create a specialized data provider class.
Example uses the following XML:
<items>
<item>
<id>1</id>
<label>California</label>
</item>
<item>
<id>2</id>
<label>California location 1</label>
<parent>1</parent>
</item>
<item>
<id>3</id>
<label>California location 1 option 1</label>
<parent>2</parent>
</item>
<item>
<id>4</id>
<label>California location 1 option 2</label>
<parent>2</parent>
</item>
<item>
<id>5</id>
<label>California location 1 option 3</label>
<parent>2</parent>
</item>
<item>
<id>6</id>
<label>California location 2</label>
<parent>1</parent>
</item>
<item>
<id>7</id>
<label>California location 2 option 1</label>
<parent>6</parent>
</item>
<item>
<id>8</id>
<label>California location 2 option 2</label>
<parent>6</parent>
</item>
<item>
<id>9</id>
<label>New York</label>
</item>
<item>
<id>10</id>
<label>New York location 1</label>
<parent>9</parent>
</item>
<item>
<id>11</id>
<label>New York location 1 option 1</label>
<parent>10</parent>
</item>
<item>
<id>12</id>
<label>New York location 1 option 1</label>
<parent>10</parent>
</item>
</items>
Code that parses this xml is (given the value of the xml above is assigned to var xml:XML
var parent:XMLList;
for each (var node:XML in xml.item)
{
if (node.parent.toString() != "")
{
parent = xml.item.(id == node.parent.toString());
if (parent.parent.toString() == "")
{
parent.@["type"] = "top";
}
node.@["type"] = "child";
parent.appendChild(node);
}
}
xml = new XML(xml.toString());
while (xml.item.(@type == "child").length() > 0)
{
delete xml.item.(@type == "child")[0];
}
trace(xml);
Output is:
<items>
<item type="top">
<id>1</id>
<label>California</label>
<item type="child">
<id>2</id>
<label>California location 1</label>
<parent>1</parent>
<item type="child">
<id>3</id>
<label>California location 1 option 1</label>
<parent>2</parent>
</item>
<item type="child">
<id>4</id>
<label>California location 1 option 2</label>
<parent>2</parent>
</item>
<item type="child">
<id>5</id>
<label>California location 1 option 3</label>
<parent>2</parent>
</item>
</item>
<item type="child">
<id>6</id>
<label>California location 2</label>
<parent>1</parent>
<item type="child">
<id>7</id>
<label>California location 2 option 1</label>
<parent>6</parent>
</item>
<item type="child">
<id>8</id>
<label>California location 2 option 2</label>
<parent>6</parent>
</item>
</item>
</item>
<item type="top">
<id>9</id>
<label>New York</label>
<item type="child">
<id>10</id>
<label>New York location 1</label>
<parent>9</parent>
<item type="child">
<id>11</id>
<label>New York location 1 option 1</label>
<parent>10</parent>
</item>
<item type="child">
<id>12</id>
<label>New York location 1 option 1</label>
<parent>10</parent>
</item>
</item>
</item>
</items>
Copy link to clipboard
Copied
@kglad -- yes both formats contain identical information. Just the recieved is flat and children show their parents by referencing the parent ID number. And in the desired form children show their parents by being a child node of the parent node. Other than that they are similar.
@Andrei1 -- Thanks for the suggestion. What I ended up doing is similar.
I created a do-while loop that looks through each node. If it doesn't have a parent defined it gets added to the top level of the new xml, if it requires a parent it finds that parent and appends it as a child of that parent. Then that node gets removed from the original xml.
It does that until the original xml has a length of zero or a maximum number of loops have been reached.
The main trick I needed was the double dot operator which allowed me to search all levels of my new xml to find the necessary parent. That way I didn't have to worry about iterating down each time.
newXML..newNode.(@ID==oldNode.parent)[0]
And the way to delete nodes from xml, which isn't very self evident
delete oldNode.parent().children()[oldNode.childIndex()];
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more