1

XML ファイルを解析したい。私のXMLは次のようになります。

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
<property>
  <name>tracker</name>
  <value>localhost:58303</value>
  <description>The host and port that the MapReduce job tracker runs
  at.  If "local", then jobs are run in-process as a single map
  and reduce task.
  </description>
</property>

</configuration>

このファイルの解析には sxx 2 パーサーを使用します。element<value>の値をlocalhost から 192.168.0.5にチェーンしたいと考えています。次のような C++ コードを書きました。

#include <SAX2XMLReader.hpp>
#include <XMLReaderFactory.hpp>
#include <DefaultHandler.hpp>
#include <XMLString.hpp>"
#include <iostream>

using namespace std;
using namespace xercesc;

int main (int argc, char* args[]) {

    try {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Error during initialization! :\n";
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return 1;
    }

    char* xmlFile = "/home/project/conf/mapred.xml";
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
    parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);   // optional

    DefaultHandler* defaultHandler = new DefaultHandler();
    parser->setContentHandler(defaultHandler);
    parser->setErrorHandler(defaultHandler);

    try {
        parser->parse(xmlFile);
    }
    catch (const XMLException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return -1;
    }
    catch (const SAXParseException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return -1;
    }
    catch (...) {
        cout << "Unexpected Exception \n" ;
        return -1;
    }

    delete parser;
    delete defaultHandler;
    return 0;
}

コードがコンパイルされます。私が知りたいのは、XML ファイルの値を変更する方法です。このハンドラーを作成してコードで使用するにはどうすればよいですか? XML ファイルの値を正常に変更するために何をする必要があるかを誰か説明できますか?

4

1 に答える 1

0

SAXハンドラーAFAIKで値を変更することはできません。通常、xml から c++ オブジェクトに変換する sax ハンドラーと、オブジェクトから xml に変換するドキュメント ビルダーの両方を定義します。

一般的なアプローチは次のとおりです。sax ハンドラーを xml パーサーと共に使用してオブジェクトを取得し、オブジェクトを変更してから、ドキュメント ビルダーを使用して xml ファイルを保存します。DomWriter クラスを見てください。xerces を使用して XML ドキュメントを作成する方法を示す例もありました。

値にチェーンするタグを検索し、XML 変換プロセス全体を回避したい場合は文字列の置換を行うこともできます (ドキュメントの構造などによって異なります)。

編集: XML には、解析と構築という 2 つの側面があります。解析に関しては、sax または dom の 2 つのオプションがあります。Sax の構文解析には、ハンドラーの作成が含まれます。XML ドキュメントがスキャンされ、XML ドキュメント内の要素が検出されるとハンドラーが呼び出されます。

EG "Saw the Foo 開始タグ"

そして後で「Fooの終了タグを見た」

ハンドラーが呼び出されると、行動する機会が得られます。通常、ハンドラーのメンバーとして何らかのオブジェクトを持ち、xml ドキュメントから取得した値を使用してセッターを呼び出します。解析が完了したら、たとえば、ハンドラーで getter を呼び出して、値が設定されたオブジェクトを取得できます。sax を使用すると、sax ハンドラーでドキュメントを変更できません。

DOM ハンドラーは、メモリ内の xml ドキュメント全体を処理します。以前に xerces DOM パーサーを使用したことはありませんが、その例があるはずです。DOM はドキュメント全体をメモリに保持しているため、上で概説した sax の解析と再構築を行わずに、その場でドキュメントを変更することさえできるかもしれません。SAX を使用する前に、必ず DOM パーサーの例を調査します。

于 2011-03-25T04:54:07.183 に答える