-1

I want to make a function which finds the last item in a boost::property_tree::ptree and returns it as ptree

I have following code which finds last item, however I do not know how to pass its ptree as a return value - it should be possible, however I have not found any examples that returns a ptree without first copying it.

Reason for wanting this is to be able to handle an update of last item with new values

BOOST_FOREACH( boost::property_tree::ptree::value_type const&rowPair, pt.get_child( "" ) ) 
{
    cout << rowPair.first << ": " << endl;

    BOOST_REVERSE_FOREACH( boost::property_tree::ptree::value_type const& itemPair, rowPair.second ) 
    {
            std::cout << "\t" << itemPair.first << " ";

            BOOST_FOREACH( boost::property_tree::ptree::value_type const& node, itemPair.second ) 
            {
                    std::cout << node.second.get_value<std::string>() << " ";
            }

            std::cout << std::endl;
            //TODO: return itemPair
            break;  
    }


    std::cout << std::endl;
}

Trying to clarify it a bit more. following code line appends to an already existing entry

pt.insert(pt.get_child("item").end(), subpt.front());

this works perfectly if Items.item only have one item, however if it has multiple "Items" and multiple "item" in Items, then it will insert new entry in first Items.item

<xml>
<listOfItems>
<Items>
  <item>
  </item>
  <item> 
  ... inserts new sub pt here
  </item>
</Items>
<Items>
  <item>
  </item>
  <item> 
  ... Should insert new sub pt here
  </item>
</Items>
</listOfItems>

so in order to get what I want I somehow have to make the insert statement better or create a function which can give me the correct item and then insert into it

serup
  • 3,676
  • 2
  • 30
  • 34
  • 1
    What do you mean by "copying it"? and what happens when you simply `return` the item you found? – UnholySheep Sep 07 '16 at 11:04
  • 3
    I assume this code is supposed to be in a separate function (or else it wouldn't make much sense in *returning* something)? Then do you pass `pt` as an argument to the function? if so, what's to stop you from just doing e.g. `return itemPair`? – Some programmer dude Sep 07 '16 at 11:05
  • yes obviously it is to be in a seperate function. I initially had something like this : pt.insert(pt.get_child("Items.item").end(), subpt.front()); -- this would update Items.item with appending a new subpt to it -- however if I had multiple item entries, then it would always append to the first item in the Items list, hence the need for finding and pointing to the last entry – serup Sep 07 '16 at 11:19
  • also when I simply return the item I found, then I get compiler errors, so there is something I am doing wrong when dealing with boost ptree as a return value – serup Sep 07 '16 at 11:21
  • Then post the code and the compiler errors. Then we can help you. – UnholySheep Sep 07 '16 at 11:25
  • 2
    Please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) that you can show us, and also include the actual errors (in full and unedited, and as copy-pasted text). Then maybe we can help you with that much better. – Some programmer dude Sep 07 '16 at 11:26
  • I agree it is a difficult question - try to look at it like this : how would the return line statement look like and what should the functions definition look like? – serup Sep 07 '16 at 11:32
  • It would be nice with a serious answer to my question instead of just voting down - voting down is just too easy and very unprofessional – serup Sep 07 '16 at 11:52
  • The reason for (at least my) downvote is that your question is unclear (you keep alternating between return and find) and you have yet to answer any of the questions that have been asked in the comments (instead you seem to ask for complete code?). If you need to find the last item of a list of child nodes - boost provides a few different ways to do that, you just need to consult the docs. (If you have issues with something else, provide the errors you receive) – UnholySheep Sep 07 '16 at 12:04
  • I disagree I do answer questions - perhaps using more than a minute to understand my question would yield more info -- but to be fair it is a difficult question and I am having trouble with posing it in a simple way I hope my last update to this question helps – serup Sep 07 '16 at 12:12

1 Answers1

0

found a solution :

<?xml version="1.0" encoding="utf-8"?>
<listOfItems>
<Items>
  <Item> </Item>
  <Item> </Item>
  <Item> </Item>
  <Item> </Item>
</Items>
<Items>
  <Item> </Item>
  <Item> </Item>
  <Item> </Item>
  <Item> </Item>
   insert here...
</Items>
</listOfItems>

...

boost::property_tree::ptree::value_type findLastItem(boost::property_tree::ptree pt)
{
  ptree _empty_tree;
  BOOST_REVERSE_FOREACH(ptree::value_type &v2, pt.get_child("listOfItems", _empty_tree))
  {
   if(v2.first == "Items")
   { 
       BOOST_REVERSE_FOREACH(ptree::value_type &v3, v2.second)
       {
           if(v3.first == "Item"){
              cout << "- OK: Found Last Item " << endl;
              return v3; // then use add_child on this to append a new item 
           }
       }
   }
  }
}
serup
  • 3,676
  • 2
  • 30
  • 34
  • I admit my initial question was wage - I guess I really did not fully grasp the issue - the solution can be used, however I would like a oneliner instead of this use of multiple BOOST statements – serup Sep 07 '16 at 19:41