2

TinyXML を使用して xml ファイルからいくつかのデータを解析したいと考えています。

ここに私の text.xml ファイルの内容があります:

<?xml version="1.0" encoding="iso-8859-1"?>
<toto>
  <tutu>
    <tata>
      <user name="toto" pass="13" indice="1"/>
      <user name="tata" pass="142" indice="2"/>
      <user name="titi" pass="azerty" indice="1"/>
    </tata>
  </tutu>
</toto>

最初の要素「user」にアクセスしたい。これを行う方法は次のとおりです。

TiXmlDocument   doc("test.xml");

    if (doc.LoadFile())
    {
        TiXmlNode *elem = doc.FirstChildElement()->FirstChildElement()->FirstChildElement()->FirstChildElement();
std::cout << elem->Value() << std::endl;
}

出力: ユーザー。

しかし、コードはかなり醜く、汎用的ではありません。上記のコードと同じ動作をシミュレートするために以下のコードを試しましたが、機能せず、エラーが発生しました。

TiXmlElement *getElementByName(TiXmlDocument &doc, std::string const &elemt_value) 
{
    TiXmlElement *elem = doc.FirstChildElement(); //Tree root

    while (elem)
    {
        if (!std::string(elem->Value()).compare(elemt_value))
            return (elem);
        elem = elem->NextSiblingElement();
    }
    return (NULL);
}

おそらく、この作業を実行できるライブラリ内の特別な関数 (getElementByName 関数) を見逃していたのでしょう。値が探している要素へのポインタを取得したいだけです。誰でも私を助けることができますか?よろしくお願いします。

4

4 に答える 4

4

これを試して

TiXmlElement * getElementByName(TiXmlDocument & doc, std::string const & elemt_value) {

   TiXmlElement * elem = doc.RootElement(); //Tree root
   while (elem) {
      if (!std::string(elem - > Value()).compare(elemt_value)) return (elem);
      /*elem = elem->NextSiblingElement();*/
      if (elem - > FirstChildElement()) {
         elem = elem - > FirstChildElement();
      } else if (elem - > NextSiblingElement()) {
         elem = elem - > NextSiblingElement();
      } else {
         while (!elem - > Parent() - > NextSiblingElement()) {
            if (elem - > Parent() - > ToElement() == doc.RootElement()) {
               return NULL;
            }
            elem = elem - > Parent() - > NextSiblingElement();
         }
      }
   }
   return (NULL);
}
于 2012-12-16T10:56:12.010 に答える
0

再帰関数を lamda-function と組み合わせてハンドラーとして使用することで、XML 要素を 1 つずつ反復処理することもできます。

// 
// This function will iterate through your XML tree and call the 'parseElement' function for each found element.
//
void RecursiveXMLParse(TiXmlElement* element, std::function<void(TiXmlElement*)>& parseElement)
{
    if (element != nullptr)
    {
        parseElement(element);
        auto child = element->FirstChildElement();
        if (child != nullptr)
        {
            RecursiveXMLParse(child, parseElement);
        }

        for (auto sibling = element->NextSiblingElement(); sibling != nullptr; sibling = sibling->NextSiblingElement())
        {
            RecursiveXMLParse(sibling, parseElement);
        }
    }
}

使用法: XML ルート要素とデータ ハンドラー ラムダ関数を再帰的なパーサー関数に渡すだけです。

int main()
{
    //
    // Define your data handler labmda
    //
    std::function<void(TiXmlElement*)>parseElement = [&](TiXmlElement* e) -> void
    {
        if (std::string(elem->Value()).compare("user"))
        {
             // Parse your user data
        }
    };

    // Pass the root element along with the above defined lambda to the recursive function 
    RecursiveXMLParse(doc.RootElement(), parseElement);

    return 0;
}
于 2018-06-06T12:13:51.907 に答える