「Qtの基礎 - XML」の版間の差分
提供: MochiuWiki : SUSE, EC, PCB
| 63行目: | 63行目: | ||
<br> | <br> | ||
* CMakeLists.txtファイルを使用する場合 | * CMakeLists.txtファイルを使用する場合 | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="cmake"> | ||
# CMakeLists.txtファイル | # CMakeLists.txtファイル | ||
2024年8月24日 (土) 00:28時点における版
概要
QXmlStreamReaderクラス
QXmlStreamReaderクラスとは
QXmlStreamReaderクラスは、XMLをシンプルなストリーミングAPIで読み込むための高速パーサである。
ストリームリーダの基本的なコンセプトは、XMLドキュメントをトークンのストリームとして読み込むことである。
QXmlStreamReaderクラスとSAXの主な違いは、これらのXMLトークンの読み込み手順である。
- SAXの場合
- アプリケーションはパーサの都合に合わせてパーサからXMLイベントを受信するハンドラ (コールバック関数) を提供する必要がある。
- QXmlStreamReaderの場合
- 繰り返し文を使用して、必要なトークンを次々にリーダから取り出すことができる。
- これは、
readNextメソッドを呼び出すことで実行され、リーダは次のトークンを完了するまで入力ストリームから読み取り、tokenTypeメソッドを返す。 - その後、
isStartElementメソッドやtextメソッド等を使用してトークンを確認することにより、読み込まれているタグや要素についての情報を得ることができる。
このプルアプローチのメリットは、再帰降順パーサを構築して、XMLを異なるメソッドやクラスに分割できることである。
これにより、XMLの解析を簡単に追跡することができる。
要素の取得例
以下の例では、XMLファイルを読み込み、以下に示す要素を読み込んでいる。
- <Hypocenter> -> <Area> -> <Name>の値
- <Hypocenter> -> <Area> -> <Code>のtype属性の値
- 全ての<Observation> -> <IntensityStation> -> <Name>の値
読み込むXMLファイルを以下に示す。
<!-- 使用するXMLファイル -->
<Earthquake>
<OriginTime>2024-08-23T21:00:00+09:00</OriginTime>
<ArrivalTime>2024-08-23T21:01:00+09:00</ArrivalTime>
<Hypocenter>
<Area>
<Name>茨城県南部</Name>
<Code type="震央地名">301</Code>
</Area>
</Hypocenter>
<jmx_eb:Magnitude type="Mj" description="M3.8">3.8</jmx_eb:Magnitude>
</Earthquake>
<Observation>
<Pref><Name>茨城県</Name><Code>08</Code><MaxInt>2</MaxInt>
<Area><Name>茨城県北部</Name><Code>300</Code><MaxInt>2</MaxInt>
<City><Name>小美玉市</Name><Code>0823600</Code><MaxInt>2</MaxInt>
<IntensityStation><Name>小美玉市小川*</Name><Code>0823633</Code><Int>2</Int></IntensityStation>
<IntensityStation><Name>小美玉市上玉里*</Name><Code>0823635</Code><Int>2</Int></IntensityStation>
</City>
<City><Name>水戸市</Name><Code>0820100</Code><MaxInt>1</MaxInt>
<IntensityStation><Name>水戸市千波町*</Name><Code>0820121</Code><Int>1</Int></IntensityStation>
</City>
</Area>
</Pref>
</Observation>
- Qtプロジェクトファイルを使用する場合
# Qtプロジェクトファイル
QT += xml
- CMakeLists.txtファイルを使用する場合
# CMakeLists.txtファイル
# ...略
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core)
# ...略
target_link_libraries(<ターゲット名> PRIVATE
Qt${QT_VERSION_MAJOR}::Core
)
#include <QCoreApplication>
#include <QXmlStreamReader>
#include <QFile>
#include <QDebug>
void parseXml(const QString& xmlData)
{
QXmlStreamReader xml(xmlData);
QString hypocenterAreaName;
QString hypocenterAreaCodeType;
QStringList intensityStationNames;
while (!xml.atEnd() && !xml.hasError()) {
QXmlStreamReader::TokenType token = xml.readNext();
if (token == QXmlStreamReader::StartElement) {
if (xml.name() == "Hypocenter") {
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "Hypocenter")) {
if (xml.tokenType() == QXmlStreamReader::StartElement) {
if (xml.name() == "Area") {
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "Area")) {
if (xml.tokenType() == QXmlStreamReader::StartElement) {
if (xml.name() == "Name") {
hypocenterAreaName = xml.readElementText();
}
else if (xml.name() == "Code") {
hypocenterAreaCodeType = xml.attributes().value("type").toString();
}
}
xml.readNext();
}
}
}
xml.readNext();
}
}
else if (xml.name() == "Observation") {
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "Observation")) {
if (xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == "IntensityStation") {
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "IntensityStation")) {
if (xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == "Name") {
intensityStationNames.append(xml.readElementText());
}
xml.readNext();
}
}
xml.readNext();
}
}
}
}
if (xml.hasError()) {
qDebug() << "XMLエラー: " << xml.errorString();
}
else {
qDebug() << "Hypocenter Area Name: " << hypocenterAreaName;
qDebug() << "Hypocenter Area Code Type: " << hypocenterAreaCodeType;
qDebug() << "Intensity Station Names: ";
for (const auto& name : intensityStationNames) {
qDebug() << " -" << name;
}
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file("sample.xml");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "XMLファイルのオープンに失敗";
return -1;
}
QString xmlData = file.readAll();
file.close();
parseXml(xmlData);
return a.exec();
}