如何将 xml 的一部分作为字符串
How to get part of xml as string
我在其他语言中看到了类似的问题,但在使用 C++ 的 Qt 中却没有。我只能得到一个 xml 数据的字符串。在这个字符串数据中有多个xml。第一个有给我的说明,另一个我应该只复制到另一个文件。就像这个例子:
<response>
<path>C:/foo.xml</path>
<language>en</language>
<xmlToCopy>
<someField1>
<nest1></nest1>
<next2></next2>
</someField1>
<someField2>bar</someField2>
</xmlToCopy>
</response>
到目前为止,我一直在使用 QString 来获取以 <xmlToCopy>
开头并以 </xmlToCopy>
结尾的子字符串,但它非常容易出错且速度很慢。在特定字段之间是否还有其他获得 xml 部分的可能性?
编辑1:
我正在通过 2 个步骤解析此 xml:
- 使用 QXmlStreamReader 来解析我期望的字段(在此示例中:"path" 和 "language")。
- 使用子字符串在 xmlToCopy 字段
下剪切文本
xmlToCopy 字段下的内容未知,我不想阅读它。我只想将它复制到其他文件。
编辑2:
我只想从上面的例子中提取这个:
<someField1>
<nest1></nest1>
<next2></next2>
</someField1>
<someField2>bar</someField2>
并将其保存到文件。
也许试试 QXmlStreamReader::readElementText() 函数?
从文档来看,它听起来像您想要的那样:
Convenience function to be called in case a StartElement was read. Reads until the corresponding EndElement and returns all text in-between.
QString text = xmlReader.readElementText(QXmlStreamReader::IncludeChildElements);
所以经过一番努力,以下应该可以满足您的需求:
QByteArray xml = "<response> \n"
" <path>C:/foo.xml</path> \n"
" <language>en</language> \n"
" <xmlToCopy> \n"
" <someField1> \n"
" <nest1></nest1> \n"
" <next2></next2> \n"
" </someField1> \n"
" <someField2>bar</someField2> \n"
" </xmlToCopy> \n"
"</response> \n";
QXmlStreamReader reader(xml);
qint64 start = 0;
qint64 end = 0;
while (!reader.atEnd()) {
if(reader.isStartElement() == true) {
if(reader.name() == "xmlToCopy") {
start = reader.characterOffset();
}
}
if(reader.isEndElement() == true) {
if(reader.name() == "xmlToCopy") {
end = reader.characterOffset();
QByteArray array = xml.mid(start, end - start - QByteArray("</xmlToCopy>").size());
array = array.trimmed();
qDebug() << "XML to Copy: \n" << array;
qDebug() << "OR : \n" << array.simplified();
}
}
reader.readNext();
}
if (reader.hasError()) {
qDebug() << "error: " << reader.errorString();
}
假设您有一个 QByteArray
,reader 可以工作。
输出为:
XML to Copy:
"<someField1>
<nest1></nest1>
<next2></next2>
</someField1>
<someField2>bar</someField2>"
OR :
"<someField1> <nest1></nest1> <next2></next2> </someField1> <someField2>bar</someField2>"
我在其他语言中看到了类似的问题,但在使用 C++ 的 Qt 中却没有。我只能得到一个 xml 数据的字符串。在这个字符串数据中有多个xml。第一个有给我的说明,另一个我应该只复制到另一个文件。就像这个例子:
<response>
<path>C:/foo.xml</path>
<language>en</language>
<xmlToCopy>
<someField1>
<nest1></nest1>
<next2></next2>
</someField1>
<someField2>bar</someField2>
</xmlToCopy>
</response>
到目前为止,我一直在使用 QString 来获取以 <xmlToCopy>
开头并以 </xmlToCopy>
结尾的子字符串,但它非常容易出错且速度很慢。在特定字段之间是否还有其他获得 xml 部分的可能性?
编辑1: 我正在通过 2 个步骤解析此 xml:
- 使用 QXmlStreamReader 来解析我期望的字段(在此示例中:"path" 和 "language")。
- 使用子字符串在 xmlToCopy 字段 下剪切文本
xmlToCopy 字段下的内容未知,我不想阅读它。我只想将它复制到其他文件。
编辑2: 我只想从上面的例子中提取这个:
<someField1>
<nest1></nest1>
<next2></next2>
</someField1>
<someField2>bar</someField2>
并将其保存到文件。
也许试试 QXmlStreamReader::readElementText() 函数?
从文档来看,它听起来像您想要的那样:
Convenience function to be called in case a StartElement was read. Reads until the corresponding EndElement and returns all text in-between.
QString text = xmlReader.readElementText(QXmlStreamReader::IncludeChildElements);
所以经过一番努力,以下应该可以满足您的需求:
QByteArray xml = "<response> \n"
" <path>C:/foo.xml</path> \n"
" <language>en</language> \n"
" <xmlToCopy> \n"
" <someField1> \n"
" <nest1></nest1> \n"
" <next2></next2> \n"
" </someField1> \n"
" <someField2>bar</someField2> \n"
" </xmlToCopy> \n"
"</response> \n";
QXmlStreamReader reader(xml);
qint64 start = 0;
qint64 end = 0;
while (!reader.atEnd()) {
if(reader.isStartElement() == true) {
if(reader.name() == "xmlToCopy") {
start = reader.characterOffset();
}
}
if(reader.isEndElement() == true) {
if(reader.name() == "xmlToCopy") {
end = reader.characterOffset();
QByteArray array = xml.mid(start, end - start - QByteArray("</xmlToCopy>").size());
array = array.trimmed();
qDebug() << "XML to Copy: \n" << array;
qDebug() << "OR : \n" << array.simplified();
}
}
reader.readNext();
}
if (reader.hasError()) {
qDebug() << "error: " << reader.errorString();
}
假设您有一个 QByteArray
,reader 可以工作。
输出为:
XML to Copy:
"<someField1>
<nest1></nest1>
<next2></next2>
</someField1>
<someField2>bar</someField2>"
OR :
"<someField1> <nest1></nest1> <next2></next2> </someField1> <someField2>bar</someField2>"