如何使用QT类和功能构建XML文件,并逃脱所有非单数字符

How do I build a XML file using Qt classes and functions and escape all non-Unicode characters?

本文关键字:逃脱 字符 单数 文件 QT 何使用 功能 XML 构建      更新时间:2023-10-16

问题

我正在尝试创建一组功能,使用户可以创建XML并将其放入XML文件中。问题是,用户可以亲自编码XML和文件编码。
因此,我对用户决定创建ASCII XML并放入ASCII文件的情况很感兴趣。问题是,他可能想将一些Unicode字符放入ASCII XML中,我想角色逃脱每个非ASCII角色。
有没有实施自己的转换器功能的方法可以做到这一点?

我尝试了...

我已经尝试过 qdomDocument 类,并且与之相关。但是它只会转换无效的XML字符:<,>& ...
而且,如果我放了一些Unicode字符,尽管我在XML声明中指示的编码。

,它将不会逃脱它们。

一些代码

我试图做这个

的示例之一
QString data("version="1.0" encoding=ASCII");
QDomProcessingInstruction instr = m_doc.createProcessingInstruction("xml", data);
m_doc.appendChild(instr);
QDomElement elem = m_doc.createElement(elemName.getQString());
QDomNode appendTo = m_current.isNull() ? m_doc : m_current;
appendTo.appendChild(elem);
m_current = elem;
QDomText text = m_doc.createTextNode(elemValue.getQString());
m_current.appendChild(text);
m_current = m_current.parentNode();

也是在尝试使用现代QXMLStreamWriter

来做到这一点
QString output;
QXmlStreamWriter stream(&output);
stream.setCodec(QTextCodec::codecForName("Windows-1250"));
stream.writeStartDocument();
stream.writeStartElement("bookmark");
stream.writeTextElement("title", "&ö");
stream.writeEndElement(); // bookmark
stream.writeEndDocument();

期望xml:

<?xml version="1.0" encoding="ASCII"?>
<Message>
  <Label>&#xF9; &lt;> &amp;' </Label>
  <Name>&amp;&#xF6;</Name>
  <Text>Hello</Text>
</Message>

实际XML:

<?xml version="1.0" encoding="ASCII"?>
<Message>
  <Label>ù &lt;> &amp;' </Label>
  <Name>&amp;ö</Name>
  <Text>Hello</Text>
</Message>

p.s。我还尝试了更具体的编码,例如Windows-1260,Windows-1268,但是它们并没有转换所有这些编码,只有ù仅转换为&#xf9;,但是ö仍保持ö。甚至在某些编码中,它也根本没有转换。

求解方法是使用您自己的编码函数。

QString encodeEntities(QString sourceText)
{
    QString tempText(sourceText);
    int len = tempText.length();
    int i = 0;
    while( i<len )
    {
        if( tempText[i].unicode() > 128  ){
            QString replaceText = "&#x"+QString::number(tempText[i].unicode(),16)+";"; // HEX format
            tempText.replace(i,1,replaceText);
            len += replaceText.length()-1;
            i += replaceText.length();
        }else{
            QString replaceText = tempText[i];
            replaceText = replaceText.toHtmlEscaped(); // Warning! Read bottom note
            tempText.replace(i,1,replaceText);
            len += replaceText.length()-1;
            i += replaceText.length();
        }
    }
    return tempText;
}

和使用QXmlStreamWriter您需要进行一些黑客攻击,请参见下文:

    QString output;
    QXmlStreamWriter stream(&output);
    stream.setCodec(QTextCodec::codecForName("utf-8"));
    stream.writeStartDocument();
    stream.writeStartElement("bookmark");       //Start bookmark
    {
        stream.writeStartElement("title");      // Start title
        stream.writeCharacters("");             // You need this to create a closed element, if not will create an open element
        output.append(encodeEntities("&ö"));    // Hack to not use the codec from QXmlStreamWriter
        stream.writeEndElement();               // End title
    }
    stream.writeEndElement();                   // End bookmark
    stream.writeEndDocument();

这对我有用,并输出以下内容:

<?xml version="1.0"?><bookmark><title>&amp;&#xf6;</title></bookmark>

注意:toHtmlEscaped()将纯文本字符串转换为带有HTML Metacharacters&lt; ,,>,&amp;和"由HTML实体代替的HTML字符串。[1]

[1] https://doc.qt.io/qt-5/qtstring.html#tohtmlescaped