4

让我首先表达我的理解,即我正在尝试做的事情正常,通常也不是很好的建议。我完全知道在普通 XML 中,该"字符是保留的。

我正在.vcxproj使用 Qt 应用程序生成要在 Visual Studio 2010 中使用的文件。我正在利用QXmlStreamWriter该类来编写项目文件所需的 XML。但是,由于 Microsoft 不遵守 XML 标准,我遇到了问题。

CustomBuild元素中,用户需要指定构建文件的命令。对于 Visual Studio 中的 Qt 项目,您最终会得到如下内容:

  <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o "..\myproj\moc_%(Filename).cpp"  -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_XML_LIB -DQT_SQL_LIB -DQT_OPENGL_LIB -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_SVG_LIB "-I." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtXml" "-I$(QTDIR)\include\QtSql" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\Qt3Support" "-I$(QTDIR)\include\QtSvg" "-I$(QTDIR)\include\QtTest" "-I..\myproj"</Command>

令人讨厌,但c'est la vie,尤其是与微软。不幸的是,我的QXmlStreamWriter对象产生了这个(完全兼容的)输出:

  <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe&quot; &quot;%(FullPath)&quot; -o &quot;..\myproj\moc_%(Filename).cpp&quot;   -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_XML_LIB -DQT_SQL_LIB -DQT_OPENGL_LIB -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_SVG_LIB &quot;-I.&quot; &quot;-I$(QTDIR)\include&quot; &quot;-I$(QTDIR)\include\QtCore&quot; &quot;-I$(QTDIR)\include\QtGui&quot; &quot;-I$(QTDIR)\include\QtXml&quot; &quot;-I$(QTDIR)\include\QtSql&quot; &quot;-I$(QTDIR)\include\QtOpenGL&quot; &quot;-I$(QTDIR)\include\Qt3Support&quot; &quot;-I$(QTDIR)\include\QtSvg&quot; &quot;-I$(QTDIR)\include\QtTest&quot; &quot;..\myproj&quot;</Command>

当然,Visual Studio 并没有留下深刻的印象。我在这里有什么选择?我可能可以读回文件并取消转义,但这听起来不是特别有效或智能。

4

2 回答 2

5

我猜您正在使用QXmlStreamWriter::writeCharacters或类似的方法来编写包含"?

也许,在调用该函数之前,您可以检查您要编写的字符串是否包含". 如果是这样,您可以将其拆分为",通过 写入非"字符QXmlStreamWriter::writeCharacters,然后"直接写入底层QIODevice

QString maybeHasQuotes = ...;
QStringList parts = maybeHasQuotes.split('"');
while (!parts.isEmpty()) {
    QString part = parts.takeFirst();
    writer.writeCharacters(part);
    if (!parts.isEmpty()) {
        writer.device()->putChar('"');
    }
}
于 2012-10-26T02:39:17.957 回答
1

直接绕过QIODevice@rohanpm 建议的方式是要走的路。

我子类化QXmlStreamWriter并添加了一个方法来编写带引号的字符串。

customstreamwriter.h

#ifndef CUSTOMSTREAMWRITER_H
#define CUSTOMSTREAMWRITER_H

#include <QXmlStreamWriter>

class CustomStreamWriter : public QXmlStreamWriter
{
public:
    CustomStreamWriter(QIODevice *device);
    void writeQuotedCharacters(QString text);
};

#endif // CUSTOMSTREAMWRITER_H

customstreamwriter.cpp

#include "customstreamwriter.h"

CustomStreamWriter::CustomStreamWriter(QIODevice *device) :
    QXmlStreamWriter(device)
{
}

void CustomStreamWriter::writeQuotedCharacters(QString text) {
    QStringList parts = text.split('"');
    while (!parts.isEmpty()) {
        QString part = parts.takeFirst();
        writeCharacters(part);
        if (!parts.isEmpty()) {
            device()->putChar('"');
        }
    }
}

我没有使用QXmlStreamWriter,而是使用 my CustomStreamWriter。唯一的区别是当我需要写一个带引号的字符串时,我调用我的writeQuotedCharacters()方法。

于 2012-10-26T20:22:44.240 回答