添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode . Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).

I have tried to remove the xmlns tag by navigating through each tag, but it cannot remove it because it cannot find the xmlns tag in the items.

QDomElement works as if there is no xmlns tag in the generatorElement content, but when I want to write to the file, it adds the xmlns tag. How can I fix it?

Xml file:

<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns="http://www.sample.com.tr/EntityConfSchema" xmlns:attr="http://www.sample.com.tr/AttributeTypes" xmlns:sim="http://www.sample.com.tr/DataTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <sample-info>
   	<sample-type>1111111</sample-type>
   </sample-info>
   <sample-initials>
   	<attribute-nvp name="sampleName">
   		<attribute xsi:type="attr:StringAttribute" value="sampleValue"/>
   	</attribute-nvp>
   	<attribute-nvp name="sampleName">
   		<attribute xsi:type="attr:StringAttribute" value="sampleValue"/>
   	</attribute-nvp>
   	<attribute-nvp name="sampleName">
   		<attribute xsi:type="attr:StringAttribute" value="sampleValue"/>
   	</attribute-nvp>
   </sample-initials>
</entity>

Here's my code:

void SampleWidget::on_pushButtonSave_clicked()
    QString entityCurrentFile = "sampleFile.entity";
    QString fileToCopy = "fileToCopy.entity";
    if (QFile::exists(entityCurrentFile))
        QFile::remove(entityCurrentFile);
    QFile::copy(fileToCopy , entityCurrentFile);
    QFile file(entityCurrentFile);
    if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
        SIM_LOG_ERROR("CANNOT OPEN");
        return;
    QDomDocument* generatorDocument = new QDomDocument;
    if (!generatorDocument->setContent(&file, true))
        return;
    file.close();
//checked the xmlData , it appears to be corrupted. There is xmlns attribute in every tag
    QByteArray xmlData = generatorDocument->toByteArray();
    QDomElement generatorElement = generatorDocument->documentElement();
    removeXmlnsAttributesFromDocument(generatorElement);
    modifyEntityFile(generatorElement);   // modify 
    QFile outputFile(entityCurrentFile);
    // Save content back to the file
    if (!outputFile.open(QIODevice::Truncate | QIODevice::WriteOnly)) {
        return;
    QTextStream stream(&outputFile);
    stream << generatorDocument->toByteArray();
    QByteArray xmlData = generatorDocument->toByteArray();
    outputFile.close();
void SampleWidget::removeXmlnsAttributesFromDocument(QDomNode& node)
    QDomNodeList children = node.childNodes();
    for (int i = 0; i < children.size(); ++i) {
        QDomNode childNode = children.at(i);
        if (childNode.isElement()) {
            QDomElement element = childNode.toElement();
            QString attributeName = "xmlns";
            if (element.hasAttribute(attributeName)) {
                element.removeAttribute(attributeName);
                qDebug() << "Attribute" << attributeName << "removed from node" << attributeName;
            else {
                qDebug() << "Node" << attributeName << "does not have attribute" << attributeName;
        removeXmlnsAttributesFromDocument(childNode);

Result:

<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns="http://www.sample.com.tr/EntityConfSchema">
	<sample-info xmlns="http://www.sample.com.tr/EntityConfSchema">
		<sample-type xmlns="http://www.sample.com.tr/EntityConfSchema">111111</sample-type>
	</sample-info>
	<sample-initials xmlns="http://www.sample.com.tr/EntityConfSchema">
		<attribute-nvp xmlns="http://www.sample.com.tr/EntityConfSchema" name="ExampleName">
			<attribute xmlns="http://www.sample.com.tr/EntityConfSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:type="attr:StringAttribute" value="ExampleValue"/>
		</attribute-nvp>
		<attribute-nvp xmlns="http://www.sample.com.tr/EntityConfSchema"  name="ExampleName">
			<attribute xmlns="http://www.sample.com.tr/EntityConfSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="attr:StringAttribute" value="ExampleValue"/>
		</attribute-nvp>
		<attribute-nvp xmlns="http://www.sample.com.tr/EntityConfSchema"  name="ExampleName">
			<attribute xmlns="http://www.sample.com.tr/EntityConfSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="attr:StringAttribute" value="ExampleValue"/>
		</attribute-nvp>
	</sample-initials>
</entity>

Expected xml file:

<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns="http://www.sample.com.tr/EntityConfSchema" xmlns:attr="http://www.sample.com.tr/AttributeTypes" xmlns:sim="http://www.sample.com.tr/DataTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<sample-info>
		<sample-type>88888888</sample-type>
	</sample-info>
	<sample-initials>
		<attribute-nvp name="ExampleName">
			<attribute xsi:type="attr:StringAttribute" value="ExampleValue"/>
		</attribute-nvp>
		<attribute-nvp name="ExampleName">
			<attribute xsi:type="attr:StringAttribute" value="ExampleValue"/>
		</attribute-nvp>
		<attribute-nvp name="ExampleName">
			<attribute xsi:type="attr:StringAttribute" value="ExampleValue"/>
		</attribute-nvp>
	</sample-initials>
</entity>
			

@Ceng0
I have had a look at this.

The text it saves may not be what you or I, as humans, would like, but it is still "correct".

It chooses to repeat the namespace attributes on each element. I believe this is deliberate/hard-coded, so that it is always right. I came across somewhere (e.g. https://codebrowser.dev/qt5/qtbase/src/xml/dom/qdom.cpp.html#_ZNK15QDomAttrPrivate4saveER11QTextStreamii):

     * QDomElementPrivate::save() output a namespace declaration if
     * the element is in a namespace, no matter what

What it is not doing is taking into account default namespace, which we would like it to do. I have not found any handling for this or way of forcing it. I agree there is some special handling where we cannot see these as attribute nodes after reading.

If you passed false instead of true to setContent() you would get the original document content back as-was. You would also see the original attributes retained. I do not know if you can work with that --- depends what you are doing with/to the document --- but that is the simplest and may be only way.

You might alternatively do your own writing via QXmlStreamWriter to get control over this, but I think that's quite a bit work and seems silly if you have a QDomDocument.

@Ceng0
I assume that you are using Qt 5 because in Qt 6 the second argument to QDomDocument::setContent() is not a bool.

Depending on your actual requirements you may be able to achieve the desired result without turning on namespace handling. This, for example, modifies the document but does not add namespace attribute everywhere:

#include <QCoreApplication>
#include <QDomDocument>
#include <QFile>
int main(int argc, char** argv) {
        QCoreApplication app(argc, argv);
        QFile file("input.xml");
        if (file.open(QIODevice::ReadOnly)) {
                QDomDocument doc;
                doc.setContent(&file, false);
                QDomElement docElem = doc.documentElement();
                QDomElement first = docElem.firstChildElement("sample-initials");
                first.setAttribute("xyzzy", "plugh");
                QFile out("output.xml");
                if (out.open(QIODevice::WriteOnly)) {
                        out.write(doc.toByteArray(2));
        return 0;

Edit: Oops, just noticed that JonB already suggested this

doc.setContent(&file, false);

Yes, that is the false for "namespace processing" I was suggesting, which would be by far the simplest. Then everything stays like it is.

But it depends on what the OP wants to do with the document read in (e.g. searching it?), if there are other namespaces involved, if they want to insert new nodes, etc.