12 Replies Latest reply on Nov 9, 2010 1:55 AM by wvxvw

    XML frustrations. Trying to insert a child in a nested XML doc....

    curtisa2

      Hi,

      I'm having a nightmare trying to do what must surely be the simplest of things,  insert an element at a specification location in a nested XML doc. As an example an XML doc...

       

      var tasks:XML =

      <myTasks>

        <year index='0' name='2009'>

          <month index='0' name='Jan'>

            <days index='0' name='1st'>

              <task1>Wash up</task1>

              <task2>Clean car</task2>

            </days>

            <days index='1' name='2nd'>

              <task1>Fix TV</task1>

            </days>

            <days index='2' name='3rd'>

              <task1>Learn Flex</task1>

              <task2>Learn AIR</task2>

            </days>

          </month>
        </year>

      </myTasks>;

       

       

      I want to add a new task for the 3rd day, so say...

      var newTask:XML = <task3>Learn XML</task3>;

       

      In actionscript I'm trying ...

       

      tasks.year.(@index == 0).month.(@index == 0).days.(@index == 2).appendChild(newTask);

       

      but it adds the new element to the 3rd day of *every* year and *every* month, not the year/months I'm specifying. I've tried many combinations in AS3 but it keeps adding to all years/months.

       

      Can anyone see what I'm doing wrong please?

       

      Many many thanks,

      Alex

        • 1. Re: XML frustrations. Trying to insert a child in a nested XML doc....
          wvxvw Level 1

          var tasks:XML =
          <myTasks>
              <year index="0" name="2009">
                  <month index="0" name="Jan">
                      <days index="0" name="1st">
                          <task1>Wash up</task1>
                          <task2>Clean car</task2>
                      </days>
                      <days index="1" name="2nd">
                          <task1>Fix TV</task1>
                      </days>
                      <days index="2" name="3rd">
                          <task1>Learn Flex</task1>
                          <task2>Learn AIR</task2>
                      </days>
                  </month>
              </year>
              <year index="1" name="2010">
                  <month index="0" name="Jan">
                      <days index="0" name="1st">
                          <task1>Wash up</task1>
                          <task2>Clean car</task2>
                      </days>
                      <days index="1" name="2nd">
                          <task1>Fix TV</task1>
                      </days>
                      <days index="2" name="3rd">
                          <task1>Learn Flex</task1>
                          <task2>Learn AIR</task2>
                      </days>
                  </month>
              </year>
          </myTasks>;

           

          var insert:XML = <task3>Learn XML</task3>;
          var where:XML = tasks.year.(@index == "0").month.(@index == "0").days.(@index == "1")[0];

           

          where.appendChild(insert);
          trace(tasks.toXMLString());

           

          Just out of curiosity, why do you need the @index attribute? Can you just use childIndex()?

          • 2. Re: XML frustrations. Trying to insert a child in a nested XML doc....
            Gregory Lafrance Level 6

            When I try to test this I get this error:

             

            The appendChild method only works on lists containing one item.

             

            How are able to do this without being in a loop parsing the data?

            • 4. Re: XML frustrations. Trying to insert a child in a nested XML doc....
              Michael Borbor Level 4

              Why would yoo need to loop when you can just transverse the xml structure?

              • 5. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                Gregory Lafrance Level 6

                I don't get an error with his original data, but you won't see hos problem, as there is only one month, one year. If you add months/years the error occurs.

                 

                I just mean his appendChild line should allow you to not have to traverse, I think, but maybe you need to traverse anyway.

                 

                Just looking for more info on his exact situation to test.

                • 6. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                  wvxvw Level 1

                  This is not an error, this is a warnig - huge difference.

                  First, you can turn it off (because the code does compile).

                  Second, you can upgrade to some later playerglobal.swc version (you'd get that warning if you're compiling against 9.115 or less).

                  • 7. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                    curtisa2 Level 1

                    Hi guys - thanks for your help..

                     

                    @wvxvw when I try what you suggested in your first reply (so with the '[0]' at the end of the 'where:XML' line which I didn't previously have) and then I do the appendChild(insert) line - I still manage to have that new 'insert' element added into every 'year' and 'month' element. It just won't append to only one day (ie for the given year and month).

                     

                    I'm using 'index' as really just a counter in my code and that is what I'm searching for when traversing. So I don't really want to have code which says "access the nth element" but rather "access the element whos index attribute is n" (because I have control over that attribute value whereas I might not have control over the order at which elements are added to a parent)

                     

                    @Greg,

                    It's the same for me no matter how many year and months I have. In my real case I've got 12 month elements, then 30/31 day child elements and under those 10 hourly child elements.  So when I try to insert a new task for just the year, month, day combination I'm specifying (via this 'index' attribute), it's adding it at the same hour for every day of every month.

                     

                    It's putting it in the right hour place as specified be the 'lowest' child element - so it's understanding the last        days.(@index=='1')     but it's doing it for all years and months.

                     
                    Could it be something to do with having to nest the elements and/or attributes in the ..

                     

                    var where:XML = tasks.year.(@index == "0").month.(@index == "0").days.(@index == "1")[0];

                     

                    line??

                     

                    Thanks

                    Alex

                    • 8. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                      Michael Borbor Level 4

                      I added manually months and years and your line of code worked, why 

                      don't you post a piece of your XML with a few days, month, and another 

                      year the problem could be the nesting.

                       

                      Sincerely,

                       

                      Michael

                      • 9. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                        wvxvw Level 1

                        [quote]@wvxvw when I try what you suggested in your first reply (so with the '[0]' at the end of the 'where:XML' line which I didn't previously have) and then I do the appendChild(insert) line - I still manage to have that new 'insert' element added into every 'year' and 'month' element. It just won't append to only one day (ie for the given year and month).[/quote]

                         

                        You must be doing it in a loop or something like that, because otherwise there isn't a chance it will be added to more than one node

                        because if you try my code "as is" you'll see that it only adds the "insert" node once...

                        Another possible reason is that you have your XML generated by multiplying the same node, i.e. if you do something like this:

                         

                        var xml:XML = <a><b/></a>;

                        xml.appendChild(xml.b[0]);

                        xml.appendChild(xml.b[0]);

                        xml.appendChild(xml.b[0]);

                        trace(xml.toXMLString());

                        xml.b[0].@foo = "bar";

                        trace(xml.toXMLString());

                         

                        Then the "b" node will be copied by reference and not by value which will totally mess your XML up... This is an old reported bug, not fixed yet.

                        • 10. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                          curtisa2 Level 1

                          Ok I guess if you were in the same place as me, I'd owe a few of you a beer or two now....

                           

                          I found the problem. It wasn't to do with the code which was trying to insert the elements, it was with an earlier function which I created to setup the skeleton for this huge xml list. I was looping through each year, then month then day etc and creating the basic xml structure (for me to then go and fill the tasks in later). When a few of you said that it was working for you, I was thinking that the only thing which was different was that the my program was looping through and creating the skeleton XML in code; whereas what I copied in the post was the trace output *after* it was created (blissfully unaware what was happening under the hood).

                           

                          So I've now manually created every year, month, day etc into a huge XML declaration and re-ran it. The inserts work perfectly and are in the right place.

                           

                          At the moment I've still not found out exactly where the problem is with my looping function but I guess I must be re-using the same object and not cleanly creating new ones to hold my child elements at each iteration (kinda Arrays 101 class I know!). This I'll look at another time; for now I've got a workaround albeit by having an ugly massive XML declaration - but I can live with that for now.

                           

                          So I'm sorry to those who actually went to recreate my sample and found it working fine !

                          • 11. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                            rickcr Level 1

                            wvxvw wrote:

                             

                            [quote]

                             

                             

                            because if you try my code "as is" you'll see that it only adds the "insert" node once...

                            Another possible reason is that you have your XML generated by multiplying the same node, i.e. if you do something like this:

                             

                             

                            var xml:XML = <a><b/></a>;

                            xml.appendChild(xml.b[0]);

                            xml.appendChild(xml.b[0]);

                            xml.appendChild(xml.b[0]);

                            trace(xml.toXMLString());

                            xml.b[0].@foo = "bar";

                            trace(xml.toXMLString());

                             

                            Then the "b" node will be copied by reference and not by value which will totally mess your XML up... This is an old reported bug, not fixed yet[/quote]

                             

                            Is this still a known issue. I was having a heck of time trying to understand why multiple attempts to append a child to some xml (even appending different nodes) was not working. Googling helped me find this post and now if I do...

                             

                            myXml.appendChild(node.copy())

                             

                            things are fine. I wish the docs were more explicit that a reference is being appending. On top of that, the behavior I was seeing was weird as all get out. The first attempt at an appendChild worked... future attempts did not work. Does the actual initial reference you append to get mucked with somehow when you do appendChild wihtout appending a copy?

                             

                            • 12. Re: XML frustrations. Trying to insert a child in a nested XML doc....
                              wvxvw Level 1

                              Oh so I see the bug is still there... I should've posted the ticket then, maybe more people would go and vote for it to be fixed... So here we go:

                              https://bugs.adobe.com/jira/browse/ASC-3706