Java XML API:適切なものを選択します。 StAX:私たちは喜びをもって仕事をします





こんにちは

2000年代初期からXML形式の人気が低下したにもかかわらず、XML形式はしっかりとその位置を占めました。 プロジェクトの60%でXML処理に出会い、Masterjavaでのインターンシップに専念しました。 その最も一般的な用途は、XHTML、SOAP、さまざまな構成(たとえば、Tomcat、SoapUI、IntelliJ IDEA、Spring XML構成)、データのインポート/エクスポートです。



JavaにはXMLを操作するためのAPIがいくつかあります。開発者は、特定の状況でどのAPIを選択するかを理解することが重要です。 この記事では、すべてのJava XML API、それらの目的と使用例を簡単にリストし、かなりまれですが、場合によっては唯一の真のStAXテクノロジーとの連携について説明します。 既にXML要素に精通ていることを前提としています。



Java XML API:適切なものを選択する





APIの機能の比較ラベルで、 SAX / StAXのEasy of Use



、作成者がStAXの操作方法を知らないことを示しており、記事の残りの部分では「適切に準備する」方法について説明します。



StAX:私たちは喜びをもって仕事をします



まず、2つのAPIを使用してStAXを操作できることに注意してくださいプリミティブを返す低レベルのXMLStreamReaderと、オブジェクトを返し、より多くのメモリを消費する高レベルのXMLEventReaderです。 次に、XMLStreamReaderを使用します。 その上にラッパーを使用すると、XMLでの作業が簡単で便利になります小さな例を見てみましょう:都市とユーザーを含む単純なXMLがあります。
  <Payload> <Cities> <City id="spb">-</City> <City id="mow"></City> ... </Cities> ... <Users> <User city="mow"> <email>gmail@gmail.com</email> <fullName>Gmail User</fullName> </User> <User city="spb"> <email>admin@javaops.ru</email> <fullName>Admin</fullName> </User> ... </Users> ... </Payload>
      
      



実際には、このXMLには数百の都市と数十万/ 100万のユーザーを含めることができます。 必要なのは、都市のリストを印刷することだけです。 この場合、StAX APIが唯一の正しい選択です。 補助クラスStaxStreamProcessor



をプロジェクトに追加します。
 public class StaxStreamProcessor implements AutoCloseable { private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance(); private final XMLStreamReader reader; public StaxStreamProcessor(InputStream is) throws XMLStreamException { reader = FACTORY.createXMLStreamReader(is); } public XMLStreamReader getReader() { return reader; } @Override public void close() { if (reader != null) { try { reader.close(); } catch (XMLStreamException e) { // empty } } } }
      
      



次に、XMLを順番に調べ、関心のあるすべてのイベントを読み取り、必要な情報を表示します。
 try (StaxStreamProcessor processor = new StaxStreamProcessor(Files.newInputStream(Paths.get("payload.xml")))) { XMLStreamReader reader = processor.getReader(); while (reader.hasNext()) { // while not end of XML int event = reader.next(); // read next event if (event == XMLEvent.START_ELEMENT && "City".equals(reader.getLocalName())) { System.out.println(reader.getElementText()); } } }
      
      



XMLで目的のイベントを検索するために頻繁に繰り返されるコードをプログラム内で絶えず複製しないように、 StaxStreamProcessor



追加できます。
 public boolean doUntil(int stopEvent, String value) throws XMLStreamException { while (reader.hasNext()) { int event = reader.next(); if (event == stopEvent && value.equals(reader.getLocalName())) { return true; } } return false; }
      
      



ユーティリティクラスの使用は簡単ではありませんが、非常に簡単です。
 while (processor.doUntil(XMLEvent.START_ELEMENT, "City")){ System.out.println(reader.getElementText()); }
      
      



このコードの欠点は、プログラムを完了する代わりに、必要のない数十万のユーザーを処理するためにリソースを費やすことはまったく役に立たないことです。 XMLのスキャンを停止するには、条件を追加する必要があります。 これは通常、親要素(この場合はCities



)のタグの終わりです。 親タグの末尾または指定された要素のいずれかにXMLをスキャンする別のユーティリティメソッドをStaxStreamProcessorに追加します。
 public boolean startElement(String element, String parent) throws XMLStreamException { while (reader.hasNext()) { int event = reader.next(); if (parent != null && event == XMLEvent.END_ELEMENT && parent.equals(reader.getLocalName())) { return false; } if (event == XMLEvent.START_ELEMENT && element.equals(reader.getLocalName())) { return true; } } return false; }
      
      



属性とテキストを読み取るためのメソッドを追加します。
 public String getAttribute(String name) throws XMLStreamException { return reader.getAttributeValue(null, name); } public String getText() throws XMLStreamException { return reader.getElementText(); }
      
      



呼び出しコードは非常にシンプルなままであり、 Cities



タグの終了後すぐにXMLの処理を停止します。
 while (processor.startElement("City", "Cities")) { System.out.println(processor.getAttribute("id") +":" + processor.getText()); }
      
      



StAX APIでは、イベントの読み取りに正確さが必要です。 出力で属性とテキストの読み取りを省略したが、コードが機能しなくなった場合:XMLから都市名を読み取った後、属性は取り残され、アクセスできなくなります。 また、XMLの現在の状況に応じて、XMLから読み取るための一部のAPIメソッドが使用できる場合と使用できない場合があることもStaxStreamProcessor



必要があります。 このアプローチにより、StAXでの作業が簡単で便利に思えることを願っています。



ご清聴ありがとうございました。コーディングをお楽しみください!



All Articles