【问题标题】:Converting QDomElement to QString / Container class将 QDomElement 转换为 QString / Container 类
【发布时间】:2010-07-14 08:27:42
【问题描述】:

假设我们有以下 XML 文档:

<root>
    <options>
        ...
    </options>
    <children>
        <child name="first">12345</child>
        <child name="second">
            <additionalInfo>abcd</additionalInfo>
    </children>
</root>

我想获取“子”节点的字符串表示并将它们附加到一个数组中(我不想丢失 XML 语法,因此 .text() 不是一个选项)。例如,第一个孩子看起来像:

QString child = "<child name="first">12345</child>";

我使用以下代码获取元素:

QDomDocument doc;
QDomElement element;
element = xml->documentElement();
if(element.isNull() == false)
{
    element = element.firstChildElement("children");
    if(element.isNull()) return;

    element = element.firstChildElement("child");
    while(element.isNull() == false)
    {
        doc = element.toDocument();
        if(doc.isNull() == false)
        {
            // save string into array
            array.append(doc.toString());
        }
        element = element.nextSiblingElement("child");
    }
}

问题是 doc.isNull 总是返回 false(看起来我无法将元素转换为文档)。有什么办法可以做到这一点?

编辑:

我想补充一点,这里 QString 不是强制性的。基本上任何可以稍后用于检索数据的类都可以(我将保存这些节点并稍后使用它们来初始化另一个对象)。重要的是,即使原始文档已被破坏,我也应该能够访问这些值。例如,可以将这些元素直接存储到某个数组(例如 QList)中,以便以后访问它们。

【问题讨论】:

    标签: qt qtxml


    【解决方案1】:

    我会为我自己的问题添加一个答案。不知道为什么,但看起来我错过了文档中的以下功能。

    void QDomNode::save ( QTextStream & str, int indent ) const

    它几乎完成了将节点转换为字符串所需的所有工作,例如:

    QString str;
    QTextStream stream(&str);
    QDomNode node = xml->documentElement().firstChildElement("child");
    
    node.save(stream, 4 /*indent*/);
    
    // process str
    

    【讨论】:

    • 相反的操作呢?给定字符串生成一个 QDomNode,以后可以将其附加到现有的 QDomDocument 中?
    • @Pierluigi,这本身应该是一个问题。它涉及很多。您创建一个QDomDocument,使用setContent(),然后使用QDomDocumentFragment 将结果复制到另一个文档中...
    • 评论 /* = 4 * 没有关闭。所以这里语法错误。
    • No idea why, but looks like I missed the following function 可能是因为没有人期望save 而我们通常会寻找序列化或toByteArray 或toXmlString...
    【解决方案2】:

    由于您需要 XML 格式本身,因此您不需要 QDomElementQDomDocumentQDomElementQDomDocument 用于获取存储在XML 文档中的数据

    你只需要一个普通的文件遍历。

    使用

    打开文件
    bool QFile::open ( OpenMode mode )   [virtual]
    

    您可以通过以下方式读取文件的全部内容,

    QByteArray QIODevice::readAll ()
    

    您可以将其分配给QString

    例如,

    QString entireContents = xmlFile->readAll();
    

    然后你可以使用 newline \n 字符分割整个内容

    QStringList QString::split ( const QString & sep, SplitBehavior behavior = KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const
    

    现在每个索引对应于 XML 文件中的每一行。您可以遍历它并获得所需的兴趣线。

    希望对你有帮助...

    【讨论】:

    • 请回复。我正在使用那些 QDom* 类,因为我还需要在讨论的操作之前解析/获取大量数据。这就是为什么我很好奇这些是否可以通过这些类(或任何 QtXml 类)来完成。我知道可以“手动”解析文档,并且可以使用简单的文档。但是,在我的情况下,文档可能非常复杂,我需要在多个地方进行类似的操作。基本上我所知道的是,在 XML 树的某个级别上应该有一个节点,我需要得到它下面的每个分支。
    【解决方案3】:

    嗯,我认为你不能用 Qt XML 类做你想要的,但应该可以自己简单地重建字符串(也许不是 100% 匹配原始字符串,但具有相同的含义),基于Qt XML 类提供的方法。

    编辑: 小代码 sn-p 可能会做的事情(未经测试):

    QString domElementToRawXML(const QDomElement& elem)
    {
        QString head = "<"+elem.tagName();
        QDomNamedNodeMap attrs = elem.attributes();
        for(int i = 0; i<attrs.size(); ++i)
        {
            QDomAttr attr = attrs.item(i).toAttr();
            head += 
                QString::fromLatin1(" %0=\"%1\"")
                .arg(attr.name())
                .arg(attr.value());
        }
        head += ">";
        return head + elem.text() + "</"+elem.tagName()+">";
    }
    

    【讨论】:

    • 感谢您的回复。基于这些答案,看来我必须放弃保存节点(作为字符串)的策略并找出其他东西。
    猜你喜欢
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 2019-12-23
    • 2011-08-21
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多