简体   繁体   中英

Parsing XML elements using TinyXML?

I am trying to parse an xml file and obtain certain attributes from it to store. I can successfuly parse the document if every element is present, but in some instances an element is not present for a specific node, and because of this I receive a segmentation fault because I am creating a pointer to an element which doesn't exist. The following is an XML file I am parsing.

<recipe>
  <title>Hippie Pancakes</title>

  <recipeinfo>
    <blurb>Socially conscious breakfast food.</blurb>

    <author>David Horton</author>

    <yield>12 to 16 small pancakes, enough for two hippies</yield>

    <preptime>10 minutes</preptime>
  </recipeinfo>

  <ingredientlist>
    <ingredient><quantity>1</quantity> <unit>C.</unit> <fooditem>unbleached
     wheat blend flour</fooditem></ingredient>

    <ingredient><quantity>2</quantity> <unit>tsp.</unit> <fooditem>baking
    powder</fooditem></ingredient>

    <ingredient><quantity>1</quantity> <unit>tsp.</unit> <fooditem>unrefined
    sugar</fooditem></ingredient>

     <ingredient><quantity>1/4</quantity> <unit>tsp.</unit> <fooditem>coarse
    kosher salt</fooditem></ingredient>

    <ingredient><quantity>1</quantity> <fooditem> free-range egg</fooditem></ingredient>


   </ingredientlist>
 </recipe>

I do not read the <recipeinfo> element, and only need the title and ingredients. However, the last ingredient, does not have a unit, and instead only has a quantity and the name of the fooditem. Reaching the last ingredient gives me a segmentation fault. I am trying to check to see if the element exists, but the code I have to do so is skipped over.

TiXmlElement* recipeinfo = title->NextSiblingElement();
TiXmlElement* ingredientlist = recipeinfo->NextSiblingElement();
TiXmlElement* ingredient = ingredientlist->FirstChildElement();
if (ingredient){
    iterate(ingredient);
}

 void iterate(TiXmlElement* ingredient){
    TiXmlElement* quantity = ingredient->FirstChildElement("quantity");
    if (quantity->NextSiblingElement()){
        double quantity_ = atof(quantity->GetText());
        cout << " " << quantity_ << flush;  

        TiXmlElement* unit = quantity->NextSiblingElement("unit");
        string name = unit->Value();
        cout << name;
        if (unit->NextSiblingElement()){

            string unit_ = unit->GetText();
            cout << " " << unit_ << flush;

            TiXmlElement* fooditem = unit->NextSiblingElement("fooditem");

            string fooditem_ = fooditem->GetText();
            cout << " " << fooditem_ << flush;
        }  
        else{
            TiXmlElement* fooditem = quantity->NextSiblingElement("fooditem");
            string fooditem_ = fooditem->GetText();
            cout << fooditem->Value();
            cout << " " << fooditem_ << flush;
        }
    }

    TiXmlElement* nextIngredient = ingredient->NextSiblingElement();

    if (ingredient->NextSiblingElement())
        iterate(nextIngredient);         
}

unit->value and unit->NextSibilingElement should be called only if 'unit' is not NULL. Same goes for all the pointers that you use in this example Edit. In your case, for the last ingredient, unit is NULL, and unit->value should be the line making the application crash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM