Question

I am trying to parse the following xml using tiny xml parser.I am trying to get the value of all producer and consumer attributes of q2channel tag in the xml file.I am using tinyxml2.

So far I have written the following code but I am stuck here as when I try to print something I get null.

XMLDocument doc;
    bool loadOkay=doc.LoadFile( "resources/q2profiling.xml" );


    XMLElement* titleElement = doc.FirstChildElement()->FirstChildElement();
    const char* title = titleElement->GetText();
    printf( "The remaining xml is %s\n", title );

I have tried several different variations of the code to progress my work but I am stuck here.Please help me in printing the value of all consumer and producer attributes of q2channel tag from the xml.

The xml file is given below

<

?xml version="1.0" encoding="UTF-8" ?>
<q2:profiles xmlns:q2="http://www.example.org/q2profiling" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/q2profiling q2profiling.xsd">
    <q2:application name="testAPPlication">
        <q2:QDUGraph>
            <q2:channel producer="UNKNOWN_PRODUCER(CONSTANT_DATA)" consumer="Out_of_the_main_function_scope">
                <q2:UnMA>19298</q2:UnMA>
                <q2:Bytes>25892</q2:Bytes>
                <q2:UnDV>19298</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134512692" upper="134512695" />
                    <q2:range lower="134512700" upper="134512703" />        
                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="UNKNOWN_PRODUCER(CONSTANT_DATA)" consumer="main">
                <q2:UnMA>160</q2:UnMA>
                <q2:Bytes>234</q2:Bytes>
                <q2:UnDV>160</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134513084" upper="134513087" />
                    <q2:range lower="134513116" upper="134513119" />
                    <q2:range lower="134513129" upper="134513129" />
                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="Out_of_the_main_function_scope" consumer="Out_of_the_main_function_scope">
                <q2:UnMA>1474</q2:UnMA>
                <q2:Bytes>14815</q2:Bytes>
                <q2:UnDV>2468</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134520828" upper="134520831" />
                    <q2:range lower="134520836" upper="134520843" />
                    <q2:range lower="3077693172" upper="3077693175" />

                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="Out_of_the_main_function_scope" consumer="main">
                <q2:UnMA>209</q2:UnMA>
                <q2:Bytes>381</q2:Bytes>
                <q2:UnDV>209</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134520836" upper="134520847" />
                    <q2:range lower="3045611784" upper="3045611795" />

                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="main" consumer="Out_of_the_main_function_scope">
                <q2:UnMA>40</q2:UnMA>
                <q2:Bytes>60</q2:Bytes>
                <q2:UnDV>40</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="3048639008" upper="3048639019" />
                    <q2:range lower="3048639024" upper="3048639031" />

                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="main" consumer="main">
                <q2:UnMA>32</q2:UnMA>
                <q2:Bytes>444</q2:Bytes>
                <q2:UnDV>88</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="3048639008" upper="3048639011" />
                    <q2:range lower="3048639016" upper="3048639019" />

                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="UNKNOWN_PRODUCER(CONSTANT_DATA)" consumer="sum">
                <q2:UnMA>1</q2:UnMA>
                <q2:Bytes>1000</q2:Bytes>
                <q2:UnDV>1</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134520860" upper="134520860" />
                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="UNKNOWN_PRODUCER(CONSTANT_DATA)" consumer="diff">
                <q2:UnMA>1</q2:UnMA>
                <q2:Bytes>1000</q2:Bytes>
                <q2:UnDV>1</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134520860" upper="134520860" />
                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="init" consumer="sum">
                <q2:UnMA>2000</q2:UnMA>
                <q2:Bytes>2000</q2:Bytes>
                <q2:UnDV>2000</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134520896" upper="134521895" />
                    <q2:range lower="134523968" upper="134524967" />
                </q2:UnMARanges>
            </q2:channel>
            <q2:channel producer="init" consumer="diff">
                <q2:UnMA>2000</q2:UnMA>
                <q2:Bytes>2000</q2:Bytes>
                <q2:UnDV>2000</q2:UnDV>
                <q2:UnMARanges>
                    <q2:range lower="134520896" upper="134521895" />
                    <q2:range lower="134523968" upper="134524967" />
                </q2:UnMARanges>
            </q2:channel>
        </q2:QDUGraph>
    </q2:application>
</q2:profiles>
Was it helpful?

Solution

The function GetText() won't give you the actual name of the node in question, but the text inside the node. For instance, invoking GetText() on this hypothetical node

<node>This is text!</node>

will yield "This is text!" as a const char* or a const std::string& depending on how you compile. See the API reference of TiXmlElement.

If you want to query the node name itself, use TiXmlNode::Value().

If you want an attribute, simply use Attribute(const char*) or QueryStringAttribute(...) on the element. For instance, retrieving and printing the following with the document you provided

std::cout << doc.FirstChildElement ()->FirstChildElement ()->Attribute ("name") << std::endl;

yields "testAPPlication".

In general, see the full documentation of TinyXML first.

EDIT: The following example depicts in a simple, yet ugly way what you need:

TiXmlDocument doc;

if(doc.LoadFile ("test.xml"))
{
  TiXmlElement* graphElem   = doc.FirstChildElement()->FirstChildElement ()->FirstChildElement ();
  TiXmlElement* channelElem = graphElem->FirstChildElement ();

  for(; channelElem; channelElem = channelElem->NextSiblingElement ())
  {
    std::cout << channelElem->Attribute ("producer")
              << " | "
              << channelElem->Attribute ("consumer")
              << std::endl;
  }
}

EDIT2: Removed infinite loop and conditional.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top