【问题标题】:Edit Value of a QDomElement?编辑 QDomElement 的值?
【发布时间】:2011-10-08 21:18:16
【问题描述】:

我需要编辑 QDomElement 的文本 - 例如

我有一个 XML 文件,其内容为 -

<root>    
    <firstchild>Edit text here</firstchild>
</root>

如何编辑子元素&lt;firstchild&gt;的文字?

我在 Qt 4.7 中提供的 QDomDocument 类描述的 QDomElement 中没有看到任何函数

Edit1 - 我正在添加更多细节。

我需要读取、修改和保存一个 xml 文件。文件格式如下-

<root>    
    <firstchild>Edit text here</firstchild>
</root>

需要编辑element的值。我读取xml文件的代码是-

QFile xmlFile(".\\iWantToEdit.xml");
xmlFile.open(QIODevice::ReadWrite);

QByteArray xmlData(xmlFile.readAll());

QDomDocument doc;
doc.setContent(xmlData);

// 读取必要的值

// 写回修改后的值?

注意:我尝试将 QDomElement 转换为 QDomNode 并使用函数 setNodeValue()。但是它不适用于 QDomElement。

我们非常欢迎任何建议、代码示例、链接。

【问题讨论】:

    标签: c++ qt qt4 qtxml


    【解决方案1】:

    这将做你想做的(你发布的代码将保持原样):

    // Get element in question
    QDomElement root = doc.documentElement();
    QDomElement nodeTag = root.firstChildElement("firstchild");
    
    // create a new node with a QDomText child
    QDomElement newNodeTag = doc.createElement(QString("firstchild")); 
    QDomText newNodeText = doc.createTextNode(QString("New Text"));
    newNodeTag.appendChild(newNodeText);
    
    // replace existing node with new node
    root.replaceChild(newNodeTag, nodeTag);
    
    // Write changes to same file
    xmlFile.resize(0);
    QTextStream stream;
    stream.setDevice(&xmlFile);
    doc.save(stream, 4);
    
    xmlFile.close();
    

    ... 一切就绪。您当然也可以写入不同的文件。在此示例中,我只是截断了现有文件并覆盖了它。

    【讨论】:

    • @Eternal Learner:别忘了也知道赏金!
    • 其实里面的文本是一个文本节点,所以你可以这样做: doc.documentElement().firstChildElement("firstchild").firstChild().setNodeValue("new text "); // 注意额外的 firstChild() 查询
    • Luke 给出的完美解决方案,在更新第二个子元素时很有用。 Peter 的解决方案是 Optimal 并且适用于快速 xml 更新,不需要像 QDomElement 和 QDomText 和 roor.replaceChild() 这样的变量声明,谢谢
    【解决方案2】:

    当您想更改节点内的文本时,只需使用更好和更简单的解决方案(类似于 Lol4t0 写的)来更新它。 'firstchild' 节点内的文本实际上变成了一个文本节点,所以你要做的是:

    ...
    QDomDocument doc;
    doc.setContent(xmlData);
    doc.firstChildElement("firstchild").firstChild().setNodeValue(‌​"new text");
    

    注意额外的 firstChild() 调用,它将实际访问文本节点并使您能够更改值。这比创建新节点和替换整个节点要简单得多,而且肯定更快且侵入性更小。

    【讨论】:

      【解决方案3】:

      有什么问题。你想写什么样的价值观? 例如,下面的代码转换这个 xml

      <?xml version="1.0" encoding="UTF-8"?>
      <document>
          <node attribute="value">
              <inner_node inner="true"/>
              text
          </node>
      </document>
      

      <?xml version='1.0' encoding='UTF-8'?>
      <document>
          <new_amazing_tag_name attribute="foo">
              <bar inner="true"/>new amazing text</new_amazing_tag_name>
      </document>
      

      代码:

      QFile file (":/xml/document");
      file.open(QIODevice::ReadOnly);
      QDomDocument document;
      document.setContent(&file);
      QDomElement documentTag = document.documentElement();
      qDebug()<<documentTag.tagName();
      
      QDomElement nodeTag = documentTag.firstChildElement();
      qDebug()<<nodeTag.tagName();
      nodeTag.setTagName("new_amazing_tag_name");
      nodeTag.setAttribute("attribute","foo");
      nodeTag.childNodes().at(1).setNodeValue("new amazing text");
      
      QDomElement innerNode = nodeTag.firstChildElement();
      innerNode.setTagName("bar");
      file.close();
      
      QFile outFile("xmlout.xml");
      outFile.open(QIODevice::WriteOnly);
      QTextStream stream;
      stream.setDevice(&outFile);
      stream.setCodec("UTF-8");
      document.save(stream,4);
      outFile.close();
      

      【讨论】:

      • setNodevalue 函数仅适用于某些元素类型。查看 Qt 文档中的方法QString QDomNode::nodeValue () const。它们提供了 setNodeValue 适用的节点列表。我需要设置QDomELement 的值。
      • 你错了。正如您在我的示例中看到的,QDomElement 不直接包含任何文本。但它包含 QDomText 元素,其中包含您的文本。如果QDomElement直接包含文本,替换时会删除该元素的所有子节点。
      【解决方案4】:

      这是您需要的代码版本。请注意,正如 spraff 所说,关键是找到文本类型的“firstchild”节点的子节点——这就是文本在 DOM 中的位置。

         QFile xmlFile(".\\iWantToEdit.xml");
          xmlFile.open(QIODevice::ReadWrite);
      
          QByteArray xmlData(xmlFile.readAll());
      
          QDomDocument doc;
          doc.setContent(xmlData);
      
          // Get the "Root" element
           QDomElement docElem = doc.documentElement();
      
          // Find elements with tag name "firstchild"
          QDomNodeList nodes = docElem.elementsByTagName("firstchild"); 
      
          // Iterate through all we found
          for(int i=0; i<nodes.count(); i++)
          {
              QDomNode node = nodes.item(i);
      
              // Check the node is a DOM element
              if(node.nodeType() == QDomNode::ElementNode)
              {
                  // Access the DOM element
                  QDomElement element = node.toElement(); 
      
                  // Iterate through it's children
                  for(QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling())
                  {
                      // Find the child that is of DOM type text
                       QDomText t = n.toText();
                       if (!t.isNull())
                       {
                          // Print out the original text
                          qDebug() << "Old text was " << t.data();
                          // Set the new text
                          t.setData("Here is the new text");
                       }
                  }
              }
          }
      
          // Save the modified data
          QFile newFile("iEditedIt.xml");
          newFile.open(QIODevice::WriteOnly);
          newFile.write(doc.toByteArray());
          newFile.close();
      

      【讨论】:

      • 这对我有用,当我将行改为“QDomText t = n.toText();”时改为阅读“QDomText t = n.firstChild().toText();”。
      【解决方案5】:
      Here is Solution to update xml tag using QdomDocument,It's work for linux ubuntu 18.04  
       steps is open xmlfile in readwrite mode, setContent of file in object of qdomdocument,update node value, save xmlfile and close xmlfile.
      
              QString filepath= QDir::homePath() + "/Book.xml";
              QFile file (filepath);
              file.open(QIODevice::ReadWrite);
              QDomDocument doc;
              doc.setContent(&file); doc.documentElement().firstChildElement("BookPrice").firstChild().setNodeValue(QString("$7777"));
               file.resize(0);
               QTextStream stream;
               stream.setDevice(&file);
               doc.save(stream, 4);
               file.close();
      

      【讨论】:

        【解决方案6】:

        将抽象级别提升到QDomNodefirstchild 是一个 QDomText 元素,因此您可以让 value()setValue(x) 处理文本本身。

        【讨论】:

        • QDomNode::firstChild 返回 QDomNode 而不是 QDomText。
        • 问题中的 QDomNode 是一个 QDomText。检查继承树。你在运行时检查节点类型and convert it
        • 不,firstchildQDomElement。它有一个孩子QDomText。我查过了。
        猜你喜欢
        • 2011-04-25
        • 1970-01-01
        • 2023-01-21
        • 1970-01-01
        • 2016-02-17
        • 2011-09-25
        • 1970-01-01
        • 1970-01-01
        • 2013-05-14
        相关资源
        最近更新 更多