如果 xml 檔案長于幾行,characterOffset 方法將停止正常作業。隨著 xml 檔案中資訊量的增加,characterOffset 方法與標簽位置的偏差更大。
代碼:
QFile file("../file-multi-hello.xml");
file.open(QIODevice::ReadOnly);
QXmlStreamReader xml;
xml.setDevice(&file);
qint64 startPositionElem = -1;
qint64 endPositionElem = -1;
while(!xml.atEnd()) {
qint64 offset = xml.characterOffset();
xml.readNext();
if (xml.isStartElement() && xml.name().toString() == "t") {
startPositionElem = offset;
}
if (xml.isEndElement() && xml.name().toString() == "t") {
endPositionElem = xml.characterOffset();
}
}
file.seek(startPositionElem);
qDebug() << file.read(endPositionElem - startPositionElem);
檔案-multi-hello.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14">
<w:body>
<w:p w14:paraId="4807E431" w14:textId="62BDDD69" w:rsidR="00E14DC7" w:rsidRDefault="00E14DC7">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>Hello world</w:t>
</w:r>
</w:p>
<w:p w14:paraId="5029BEAE" w14:textId="77777777" w:rsidR="009027BF" w:rsidRDefault="009027BF" w:rsidP="009027BF">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>Hello world</w:t>
</w:r>
</w:p>
<w:p w14:paraId="6C84EB68" w14:textId="77777777" w:rsidR="009027BF" w:rsidRDefault="009027BF" w:rsidP="009027BF">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>Hello world</w:t>
</w:r>
</w:p>
<w:p w14:paraId="4247D896" w14:textId="77777777" w:rsidR="009027BF" w:rsidRDefault="009027BF" w:rsidP="009027BF">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>Hello world</w:t>
</w:r>
</w:p>
<w:p w14:paraId="594CCA3B" w14:textId="61C8A4A1" w:rsidR="009027BF" w:rsidRDefault="009027BF" w:rsidP="009027BF">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>Hello</w:t>
</w:r>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>–</w:t>
</w:r>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>world</w:t>
</w:r>
</w:p>
<w:p w14:paraId="28E3E3B5" w14:textId="77777777" w:rsidR="009027BF" w:rsidRPr="00E14DC7" w:rsidRDefault="009027BF">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
</w:p>
<w:sectPr w:rsidR="009027BF" w:rsidRPr="00E14DC7">
<w:pgSz w:w="11906" w:h="16838" />
<w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="708" w:footer="708" w:gutter="0" />
<w:cols w:space="708" />
<w:docGrid w:linePitch="360" />
</w:sectPr>
</w:body>
</w:document>
控制臺輸出:
輸出:“<w:t>世界</w:”
上例中的 xml 檔案已格式化。輸出到控制臺而不格式化
輸出:“r><w:t>世界</w:”
如何使 characterOffset 方法正常作業?出現在控制臺中
輸出:“<w:t>世界</w:>”
PS 對于一個小的 xml 檔案,一切正常
檔案-hello.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14">
<w:body>
<w:p w14:paraId="4807E431" w14:textId="71C9FAEC" w:rsidR="00E14DC7" w:rsidRPr="00E14DC7" w:rsidRDefault="00E14DC7">
<w:pPr>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:lang w:val="en-US" />
</w:rPr>
<w:t>Hello world</w:t>
</w:r>
</w:p>
<w:sectPr w:rsidR="00E14DC7" w:rsidRPr="00E14DC7">
<w:pgSz w:w="11906" w:h="16838" />
<w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="708" w:footer="708" w:gutter="0" />
<w:cols w:space="708" />
<w:docGrid w:linePitch="360" />
</w:sectPr>
</w:body>
</w:document>
控制臺輸出:
輸出:“<w:t>Hello world</w:t>”
Qt 5.15.2 版本編譯MinGW 64bit
uj5u.com熱心網友回復:
第 72 行你有一個多位元組字符:U 2013
這個字符在 UTF-8 中使用 3 個位元組。
該函式characterOffset將其視為單個字符。但是,當您使用讀取檔案seek并使用read位元組數時。
在您的示例中,最后一個元素的字符偏移量為4940,但是它從4942th位元組開始。
要使其作業,您需要使用能夠正確處理多位元組字符的函式。一個解決方案是使用 QString:
file.seek(0);
const QByteArray data = file.readAll();
const QString str = QString::fromUtf8(data);
qDebug() << str.mid(startPositionElem, endPositionElem - startPositionElem);
另一種是使用QTextStream:
QTextStream stream(&file);
stream.seek(0);
stream.read(startPositionElem);
qDebug() << stream.read(endPositionElem - startPositionElem);
請注意,在任何情況下,您都不能直接查找多個字符,而只能查找多個位元組。這意味著您必須從檔案的開頭讀取,以便執行 unicode 決議的函式/類可以讀取和檢測多位元組字符。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/434943.html
