1

XMLツリーに4つのレベルがあると仮定すると、レベル3は同じ息子を持つことができます-2回、つまり次のXMLで:

<Game>
    <Round>
        <roundNumber>1</roundNumber>
        <Door>
            <doorName>abd11</doorName>
            <Value>
                <xVal1>0</xVal1>
                <xVal2>25</xVal2>
                <pVal>0.31</pVal>
            </Value>
            <Value>
                <xVal1>25</xVal1>
                <xVal2>50</xVal2>
                <pVal>0.04</pVal>
            </Value>
            <Value>
                <xVal1>50</xVal1>
                <xVal2>75</xVal2>
                <pVal>0.19</pVal>
            </Value>
            <Value>
                <xVal1>75</xVal1>
                <xVal2>100</xVal2>
                <pVal>0.46</pVal>
            </Value>
        </Door>
        <Door>
            <doorName>vvv1133</doorName>
            <Value>
                <xVal1>60</xVal1>
                <xVal2>62</xVal2>
                <pVal>1.0</pVal>
            </Value>
        </Door>
    </Round>
    <Round>
        <roundNumber>2</roundNumber>
        <Door>
            <doorName>eee</doorName>
            <Value>
                <xVal1>0</xVal1>
                <xVal2>-25</xVal2>
                <pVal>0.31</pVal>
            </Value>
            <Value>
                <xVal1>-25</xVal1>
                <xVal2>-50</xVal2>
                <pVal>0.04</pVal>
            </Value>
            <Value>
                <xVal1>-50</xVal1>
                <xVal2>-75</xVal2>
                <pVal>0.19</pVal>
            </Value>
            <Value>
                <xVal1>-75</xVal1>
                <xVal2>-100</xVal2>
                <pVal>0.46</pVal>
            </Value>
        </Door>
        <Door>
            <doorName>cc</doorName>
            <Value>
                <xVal1>-60</xVal1>
                <xVal2>-62</xVal2>
                <pVal>0.3</pVal>
            </Value>
            <Value>
                <xVal1>-70</xVal1>
                <xVal2>-78</xVal2>
                <pVal>0.7</pVal>
            </Value>
        </Door>
    </Round>
</Game>

私はDoorsそれぞれに2つ持っていますRound、そして問題は、DomまたはSax(またはそれが役立つ場合はJdom)を使用することです

ツリーを反復処理して、すべてのレベルのデータを取得しますか?

現時点では、レベルを「下げて」ラウンドを取得しました。ここで:

  DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    Document doc = docBuilder.parse (new File("input.xml"));

    // normalize text representation
    doc.getDocumentElement ().normalize ();
    System.out.println ("Root element of the doc is " +    // would produce Game
         doc.getDocumentElement().getNodeName());


    NodeList roundNodes = doc.getElementsByTagName("Round");   // roundNodes are the Rounds 
    int totalNodes = roundNodes.getLength();                   // 2 by the example 
    System.out.println("Total number of Rounds are : " + totalNodes);   


    for (int i = 0; i < roundNodes.getLength() ; i++)

    {
        Node node = roundNodes.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE)
        {
            Element element = (Element)node;
            NodeList firstDoorList = element.getElementsByTagName("Door");
            Element firstDoorElement = (Element)firstDoorList.item(0);

            NodeList textFNList = firstDoorElement.getChildNodes();
            System.out.println("First Door : " + ((Node)textFNList.item(0)).getNodeValue().trim());
        }
    }

しかし、それは反復のための多くのコードのようです。

そのXMLのデータを抽出する簡単な方法はありますか?ラウンドごとに2つのドアがあり、ラウンド数がいくらかあると仮定します。

ありがとう

4

1 に答える 1

2

このようなコンテンツの解析は、私がSJXPを作成した理由の 1 つです。「なんてことだ、別の自家製ライブラリではない!」ということはわかっていますが、絶望しないでください。これは、上に構築された使いやすいライブラリです。 STAX パーサー仕様に準拠しているため、XPath のすべての容易さを利用して、DOM で行うようなオーバーヘッドは発生しません。フィード パーサー (RDF、RSS、ATOM) を 1 年以上手書きで作成した結果、自分の作業が複雑になればなるほど、すべてが類似していることに気付き、コア テナントを 1 つにまとめました。シンプルで高速なライブラリ (オーバーヘッドは SAX パーサーよりも少なく、依存関係を追加せずに Android でも実行されます)。

ライブラリの要点は、必要な XML 内のすべての要素を対象とする一連のルールを定義することです。解析するすべての XML データが CHARACTER データ (タグ内の属性データではない) である場合、一連の文字ルールを次のように定義します。

IRule roundNumRule = new DefaultRule(Type.CHARACTER, "/Game/Round/roundNumber") {
    @Override
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        System.out.println("Round Parsed: " + text);
    }
}

IRule doorNameRule = new DefaultRule(Type.CHARACTER, "/Game/Round/Door/doorName") {
    @Override
    public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        System.out.println("Door Name: " + text);
    }
}

...など -- 他のルールのパスは次のようになります。

  • /ゲーム/ラウンド/ドア/値/xVal1
  • /ゲーム/ラウンド/ドア/値/xVal2
  • /ゲーム/ラウンド/ドア/値/pVal

すべてのルールを作成したら、次のようにXMLParser インスタンスを作成し、作成したすべてのルールを与えます。

XMLParser parser = new XMLParser(roundNumRule, doorNameRule, <more rules>);

次に、それを使用して、解析メソッドの 1 つを介して XML のストリームを表す有効なInputStreamインスタンスを入力することにより、XML を解析します。

XMLParser インスタンスを何度も安全に再利用できます (同時に別々のスレッドで再利用することはできません)。

どの roundNumber の Door の値を読み込んでいるか、どの Door にどの値を入力しているかを把握している限り、状態を追跡する必要がありますが、これは簡単に行うことができます。単純な Java POJO を作成して、構造化して ArrayList に格納します。次に例を示します。

List<Round> roundList = new ArrayList<Round)();

「丸い」POJO が次のようになっているとします。

public class Round {
    public int number;
    public List<Door> doorList;
}

Door POJO は次のようになります。

public class Door {
    public String name;
    public int xVal1;
    public int yVal2;
    public double pVal;
}

最上位のroundListは、解析された値のルートを表し、それを解析操作に直接渡すことができます。これは、SJXP Javadocsで参照されている userObject です。

ルールが一致すると、その userObject がルールに渡されるので、渡したリストにアクセスできるようになります。

roundNumRule の場合、新しい Round POJO を作成し、roundNumber 値を割り当ててリストに追加します。

doorNameRule の場合、リストから最後の Round を取得し、新しい Door POJO を追加して、その名前をそれに割り当てます。

等々...

それが役立つことを願っています!

于 2012-05-05T15:38:44.170 に答える