2017-05-10 17 views
1

C++(!11)/ QTのXMLファイルを各値とそのxmlタグの親構造を保持するベクトルに解析する必要があります。qtでXMLを解析してツリー構造を取得

私はQTが新しく、ライブラリにいくつかの良いオプションがあることを知っています。しかし、私が見つけたものの多くは、タグ名を事前に知っている人たちに焦点を当てています。私にとっては、より一般的なものが必要です。タグ名(と値)は私の目的とは無関係で、何でもかまいません。私の焦点は各値を保持するタグ構造にあります。これのために取る最良のアプローチは何ですか? QDomDocument?

*注:実際のxmlはツリー構造の長さがはるかに複雑になります。

例入力

Test.xmlを

<MainTag> 
<description>Test Description</description> 
<type>3</type> 
<source> 
    <description>Source test Description1</description> 
    <type>4</type> 
</source> 
<source> 
    <description>Source test Description2</description> 
    <type>5</type> 
    <name> 
     <element>1</element> 
    </name> 
</source> 

</MainTag> 

出力例

(文字列行がC++ベクターに含まれる):

description=Test Description 
type=3 
source.description=Source test Description1 
source.type=1 
source.description=Source test Description2 
source.type=2 
source.name.element=1 
+0

ルック](http://doc.qt.io/qt-5/qxmlstreamreader.html)。 – MrEricSir

+0

第2の「」は「」ではありませんか? – cbuchart

+0

@cbuchartあなたは正しいです、私はそれを更新しました。ありがとう! – JavaBeast

答えて

2

XML Fを解析ile XMLのDOMをより柔軟にナビゲートするには、ストリームパーサーを使用するよりも、コードが要素の順序を認識しにくく、構造とコンテンツに重点を置いているためです。 QDomDocument::setContent

  • は、文書要素(の親要素を抽出し使用してXMLファイルの内容を持つ文書のinit

    例のコードを持っている属性にアクセスする必要がある場合は要素ではなく、最初のノードは、

  • (以下のコードを参照してください)

    このコードはXMLを解析し、タグ名とそのテキストを抽出します。属性や空のノードは抽出されません。

    注:私は指定の例<MainTag>から終了タグを</MainTag>に修正しました。

    #include <QtXml> 
    #include <QtCore> 
    #include <vector> 
    #include <iostream> 
    
    // Recursive function to parse the XML 
    void parseXML(const QDomElement& root, const QString& baseName, std::vector<QString>& v) 
    { 
        // Extract node value, if any 
        if (!baseName.isEmpty() && !root.firstChild().nodeValue().isEmpty()) { // the first child is the node text 
        v.push_back(baseName + "=" + root.firstChild().nodeValue()); 
        } 
    
        // Parse children elements 
        for (auto element = root.firstChildElement(); !element.isNull(); element = element.nextSiblingElement()) { 
        parseXML(element, baseName + "." + element.tagName(), v); 
        } 
    } 
    
    int main(int argc, char* argv[]) 
    { 
        const QString content = "<MainTag>" 
              "<description>Test Description</description>" 
              "<type>3</type>" 
              "<source>" 
              " <description>Source test Description1</description>" 
              " <type>4</type>" 
              "</source>" 
              "<source>" 
              " <description>Source test Description2</description>" 
              " <type>5</type>" 
              " <name>" 
              "  <element>1</element>" 
              " </name>" 
              "</source>" 
              "</MainTag>"; 
        std::vector<QString> v; 
    
        QDomDocument xml("xml"); 
        xml.setContent(content); 
        parseXML(xml.documentElement(), "", v); // root has no base name, as indicated in expected output 
    
        for (auto it = v.begin(); it != v.end(); ++it) { 
        std::cout << it->toStdString() << std::endl; 
        } 
    
        return 0; 
    } 
    

    次のコードのようなものでsetContentライン(エラーは単純化のために省略チェック)を変更したファイルからDOMを移入する

    ファイルからDOM:[QXmlStreamReaderで

    QFile file(filePath); 
    file.open(QFile::ReadOnly); 
    xml.setContent(file.readAll()); 
    
  • +0

    これ以上のことがありました、ありがとうございました!私はおそらく私の質問ではっきりされていなかったが、私のC + +バージョンは11より前だが、それを修正した後、それは素晴らしい仕事をした。もう一度ありがとう! – JavaBeast

    関連する問題