2

xml を解析するときに問題が発生しました。xml 形式は次のようになります。

<root>
   <menu>
       <items>
           <menu>
               <items>               
                   <menu>
                       <content/>
                   </menu>
                   <menu>
                       <content/>
                   </menu>
                   <menu>
                       <content/>
                   </menu>
               <items>               
           </menu>
           <menu>
               <items>               
                   <menu>
                       <content/>
                   </menu>
                   <menu>
                       <content/>
                   </menu>
                   <menu>
                      <items>               
                         <menu>
                             <content/>
                         </menu>
                         <menu>
                             <content/>
                         </menu>
                         <menu>
                             <content/>
                         </menu>
                      <items>
                   </menu>
               <items>
           </menu>
       </items>
   </menu>
</root>

xml の深さがわからない...... is を読んでいる間にこの xml を解析するために 2 つの sax パーサーを使用できますか?

4

2 に答える 2

3

うん、それはできる。org.xml.sax実装を使用していると仮定します(ただし、基本的な手法はすべてのSAXタイプのパーサーで機能するはずです)。

SAXを使用する場合XMLParser、実際の解析を実行するがあり、インターフェイスを実装するオブジェクト(たとえば)をSAXに渡しContentHandlerます。

メニューとは別に項目を処理したい場合は、2つ ContentHandlersのsayItemContentHandlerとを使用しますMenuContentHandler。各ハンドラーで、他のハンドラーで処理するコンテンツに遭遇しXMLReaderた場合は、代わりに他のハンドラーを使用するように指示するだけです。

<menu>タグに含まれるすべてのものを、で処理し、タグMenuContentHandler内のすべて<items>をで処理するItemContentHandler場合は、次のようにします。

class MenuContentHandler implements ContentHandler
{
    public XMLReader reader;
    public ItemContentHandler itemHandler;

    ...
    public void startElement(java.lang.String uri, java.lang.String localName,
        java.lang.String qName, Attributes atts)
    {
        if (localName.equals("items"))
            reader.setContentHandler(itemHandler); // Point 1
    }
    ...
    public void endElement(java.lang.String uri, java.lang.String localName,
        java.lang.String qName)
    {
        if (localName.equals("menu"))
            reader.setContentHandler(itemHandler); // Point 2
    }
    ...
}

class ItemContentHandler implements ContentHandler
{
    public XMLReader reader;
    public MenuContentHandler menuHandler;

    ...
    public void startElement(java.lang.String uri, java.lang.String localName,
        java.lang.String qName, Attributes atts)
    {
        if (localName.equals("menu"))
            reader.setContentHandler(menuHandler); // Point 3
    }
    ...
    public void endElement(java.lang.String uri, java.lang.String localName,
        java.lang.String qName)
    {
        if (localName.equals("items"))
            reader.setContentHandler(menuHandler); // Point 4
    }
    ...
}
...
void doParsing ( )
{
    XMLReader reader = XMLReaderFactory.createXMLReader();
    MenuContentHandler menuHandler = new MenuContentHandler(reader);
    ItemContentHandler itemHandler = new ItemContentHandler(reader);

    menuHandler.itemHandler = itemHandler;
    itemHandler.menuHandler = menuHandler;

    reader.setContentHandler(menuhandler);
    reader.parse (/*your document*/);
}

世界で最高のコードではありませんが、うまくいけば、それが意味を成し遂げます...もっと必要な場合は、私に知らせてください。

編集:これがどのように機能するか-次のXMLスニペットを想像してみてください:

 1    <menu>
 2        <items>
 3            <menu>
 4                <content/>
 5            </menu>
 6            <menu>
 7                <content/>
 8            </menu>
 9            <menu>
10                <content/>
11            </menu>
12        </items>
13    </menu>

リーダーがこのスニペットで開始するとき、ItemContentHandlerが制御されていると想定します。

最初に遭遇するのは<menu>1行目のタグです。これはメニュー項目の開始を示しているMenuContentHandlerので、メニュー要素の内容を読み取ることができるように(これは上記の「ポイント3」とマークされています)に切り替えます。

この場合、要素の最初のものは実際にはitem要素(2行目)であるため、同じようにItemContentHandler、item要素のコンテンツを処理できるように変更します(今回はポイント1)。

3行目は1行目の繰り返しであるため、ここでもポイント3に切り替えてMenuContentHandler、メニュー要素の内容を調べます。

次の要素は<content/>4行目のタグです。これはMenuContentHandler(前の段落で述べたように、現在担当しています)によって処理されます。

5行目では、メニューが</menu>タグで閉じています。これで、すべてのメニュー要素がitem要素内に含まれているため、メニューを含むitem要素内にいる必要があることがわかります。したがって、に切り替えItemContentHandlerます。これがポイント2です。

6行目は新しいメニュー項目を開始するため、1行目と3行目と同じように扱われます。7行目から11行目も同様です。

12行目はitems要素を終了し、5、8、11行目と同等のロジックにより、item要素を含むmenu要素にいる必要があることがわかります。そこで、MenuContentHandler(ポイント4)に変更します。

12行目はメニュー項目の終わりであるため、5、8、11行目と同じように扱われます。

それがもう少しよく説明されることを願っています!

于 2011-03-02T03:51:07.133 に答える
0

SAX を使用してこれを処理するには、2 つのパーサーは必要ありません。タグの開始/終了イベントごとに正しいアクションを実行するだけです。たとえば、スタックをプッシュまたはポップします。

または、DOM パーサーを使用します。

このページには、SAX パーサーと DOM パーサーの両方のチュートリアルと例へのリンクがあります。コーディングに飛び込む前に、それらを見たほうがよいでしょう。

于 2011-03-02T03:41:23.147 に答える