1

Java は初めてではありません。しかし、XML 解析に関しては比較的新しいものです。世の中に出回っている多くの XML ツールについて少しは知っていますが、どれもあまり知りません。私は XML のプロでもありません。

私の特定の問題はこれです...私は変更できないXML文書を受け取りました。そこからランダムなビットを解析してJavaオブジェクトにするだけで済みます。合理的である限り、速度はそれほど重要ではありません。同様に、メモリフットプリントも完全に最適である必要はありません。ドキュメントを 1 回読み込んで解析するだけで済みます。その後は、ドキュメントを bitbucket に投入し、POJO を使用するだけです。

それで、私は提案を受け入れます...どのツールを使用しますか?
そして、私の特定のニーズに対応するためのスターターコードを少し提案していただけませんか?

サンプル XML のスニペットと、私が作成しようとしている関連する POJO を次に示します。

<xml>
  <item id="...">
    ...
  </item>
  <metadata>
    <resources>

      <resource>
        <ittype>Service_Links</ittype>
        <links>
          <link>
            <path>http://www.stackoverflow.com</path>
            <description>Stack Overflow</description>
          </link>
          <link>
            <path>http://www.google.com</path>
            <description>Google</description>
          </link>
        </links>
      </resource>

      <resource>
        <ittype>Article_Links</ittype>
        <links>
          ...
        </links>
      </resource>

      ...

    </resources>
  </metadata>
</xml>


public class MyPojo {

    @Attribute(name="id")
    @Path("item")
    public String id;

    @ElementList(entry="link")
    @Path("metadata/resources/resource/links")
    public List<Link> links;
}

注:この質問はもともとこの質問によって生成され SimpleXmlを使用して解決しようとしていました。私は、誰かが同じ問題を解決するための別のルートを提案できるかもしれないと思ったところまで来ました。

また、注:私はCLEANソリューションを本当に望んでいます...つまり、最小限のコードで注釈やxpathを使用することです...私が最後に望むのは、巨大な扱いにくいメソッドを持つ巨大なクラスファイルです.. . それは、私はすでに持っています... 私はより良い方法を見つけようとしています.

:D

4

3 に答える 3

1

OK、それで私は(私にとって)最も合理的な方法で私のニーズに対処しているように見える解決策に落ち着きました。他の提案についてはお詫びしますが、ほとんどの解析ルールを注釈として保持し、作成する必要のある手続き型コードがごくわずかだったため、このルートの方が気に入りました。

最終的にJAXBを使用しました。当初、JAXBはJavaクラスからXMLを作成するか、XMLをJavaクラスに解析しますが、XSDのみを使用すると思いました。次に、JAXBには、XSDなしでXMLをJavaクラスに解析できるアノテーションがあることを発見しました。

私が使用しているXMLファイルは巨大で非常に深いものですが、必要なのはあちこちでほんの少しだけです。将来、何がどこにマップされるかをナビゲートするのは非常に難しいのではないかと心配していました。そこで、XMLをモデルにしたフォルダーのツリーを構築することにしました...各フォルダーは要素にマップされ、各フォルダーにはその実際の要素を表すPOJOがあります。

問題は、私が気にかけている単一のプロパティを持つ、数レベル下の子要素を持つ要素がある場合があることです。1つのプロパティにアクセスするためだけに、それぞれに4つのネストされたフォルダーとPOJOを作成するのは面倒です。しかし、それがJAXBでそれを行う方法です(少なくとも、私が言えることから)。もう一度、私は隅にいました。

次に、EclipseLinkのJAXB実装:Moxyに出くわしました。Moxyには@XPathアノテーションがあり、これをその親POJOに配置し、複数のレベルを下に移動して、すべてのフォルダーと要素-POJOを作成せずに単一のプロパティにアクセスするために使用できます。良い。

だから私はこのようなものを作成しました:(注:値をマッサージする必要がある場合にはゲッターを使用することを選択しました)

// maps to the root-"xml" element in the file
@XmlRootElement( name="xml" )
@XmlAccessorType( XmlAccessType.FIELD )
public class Xml {

    // this is standard JAXB
    @XmlElement;               
    private Item item;
    public Item getItem() {    
        return this.item;
    }

    ...
}

// maps to the "<xml><item>"-element in the file
public class Item {

    // standard JAXB; maps to "<xml><item id="...">"
    @XmlAttribute              
    private String id;
    public String getId() {
        return this.id;
    }

    // getting an attribute buried deep down
    // MOXY; maps to "<xml><item><rating average="...">"
    @XmlPath( "rating/@average" )    
    private Double averageRating;
    public Double getAverageRating() {
        return this.average;
    }

    // getting a list buried deep down
    // MOXY; maps to "<xml><item><service><identification><aliases><alias.../><alias.../>"
    @XmlPath( "service/identification/aliases/alias/text()" )
    private List<String> aliases;
    public List<String> getAliases() {
        return this.aliases;
    }

    // using a getter to massage the value
    @XmlElement(name="dateforindex")
    private String dateForIndex;
    public Date getDateForIndex() {
        // logic to parse the string-value into a Date
    }

}

また、アプリで実際に使用しているモデルオブジェクトからXMLオブジェクトを分離するルートをとったことにも注意してください。したがって、これらの粗いオブジェクトを、アプリで実際に使用するはるかに堅牢なオブジェクトに変換するファクトリがあります。

于 2012-11-05T16:22:08.497 に答える
0

XML ドキュメントが比較的小さい場合 (ここでのケースのようです)、DOM フレームワークと XPath クラスを使用します。これは、私のチュートリアルの 1つからのボイラープレート DOM/XPath コードです。

File xmlFile = ...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFile);

XPath xp = XPathFactory.newInstance().newXPath();
String value = xp.evaluate("/path/to/element/text()", doc);
// .. reuse xp to get other values as required

言い換えれば、基本的にあなたは:

  • DocumentBuilder を介して XML を Document オブジェクトに取得します。

  • XPath オブジェクトを作成します。

  • XPath.evaluate() を繰り返し呼び出し、必要な要素のパスとドキュメントを渡します。

ご覧のとおり、Document オブジェクトを取得するのは少し手間がかかり、すべての優れた XML API と同様に、ばかげた無意味なチェック例外が大量にスローされます。しかし、それを除けば、構造が比較的固定された単純な小規模から中規模の XML 文書を構文解析することは、かなりナンセンスです。

于 2012-10-08T23:52:49.380 に答える