Reputation: 1154
Let me begin by expressing my understanding that what I'm trying to do is not normal, nor is it typically well advised. I'm fully aware that in normal XML, the "
character is reserved.
I'm generating .vcxproj
files to use in Visual Studio 2010, using a Qt application. I'm taking advantage of the QXmlStreamWriter
class to write the XML needed for the project file. However, I'm running into a problem due to Microsoft's non-compliance with the XML standard.
In CustomBuild
elements, the user needs to specify the command for building the file. In the case of Qt projects within Visual Studio, you end up with something like this:
<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>
Yucky, but c'est la vie, especially with Microsoft. Unfortunatey, my QXmlStreamWriter
object produces this (fully compliant) output:
<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" "..\myproj"</Command>
Naturally, Visual Studio isn't impressed. What are my options here? I could probably read back the file and un-escape it, but that doesn't sound particularly efficient or intelligent.
Upvotes: 4
Views: 1181
Reputation: 1154
Bypassing straight to the QIODevice
the way @rohanpm suggested was the way to go.
I subclassed QXmlStreamWriter
and added a method to write quoted strings.
#ifndef CUSTOMSTREAMWRITER_H
#define CUSTOMSTREAMWRITER_H
#include <QXmlStreamWriter>
class CustomStreamWriter : public QXmlStreamWriter
{
public:
CustomStreamWriter(QIODevice *device);
void writeQuotedCharacters(QString text);
};
#endif // CUSTOMSTREAMWRITER_H
#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('"');
}
}
}
Instead of using QXmlStreamWriter
, I use my CustomStreamWriter
instead. The only difference is that when I need to write a quoted string, I call my writeQuotedCharacters()
method.
Upvotes: 1
Reputation: 4274
I guess you are using QXmlStreamWriter::writeCharacters
or similar to write the strings which contain "
?
Perhaps, before calling that function, you could check if the string you are about to write contains "
. If it does, you could split it on "
, write the non-"
characters via QXmlStreamWriter::writeCharacters
, and write "
directly to the underlying QIODevice
:
QString maybeHasQuotes = ...;
QStringList parts = maybeHasQuotes.split('"');
while (!parts.isEmpty()) {
QString part = parts.takeFirst();
writer.writeCharacters(part);
if (!parts.isEmpty()) {
writer.device()->putChar('"');
}
}
Upvotes: 5