書き込みXMLコード(B)
XMLの解析方法の4種類
XMLファイルを解析し、DOMを解析するために呼ばれ、一方はツリー構造に基づいている底部の二つの一般的な形態があり、もう一方はサックスと呼ばれるイベントストリームの形態に基づいています。より高度なパッケージングパーサーAPIに基づいてこれら二つの分析方法でも、Javaなどの生まれ基礎となるアプリケーションに基づくとJDOM DOM4J志向。
1、DOM(Document Object Model)の
DOMは、言語やプラットフォームに依存しない方法での公式のW3C標準のXMLドキュメントです。DOMは、階層的に編成されたノードまたは情報の集合体です。この階層構造により、開発者は、ツリー内の特定の情報を見つけることができます。構造の分析は、多くの場合、すべての作業を行う前にロードし、文書全体の構造的な階層構造を必要とします。それはDOMを考慮されている情報のレベルに基づいているため、ツリーベースまたはオブジェクトベース。
利点:
①、ドム全体の木がメモリにロードされ、データへのランダムリードアクセスが許可されます。
②、文書構造は、ランダム追加または削除することができます。
短所:
①、XML文書全体が1回で解析する必要があり、時間のかかります。
②、ドムツリー全体がメモリ、総メモリにロードする必要があります。
小さい文書、および文書の内容を変更する必要がありますに適用されます
2、サックス(XML用のシンプルなAPI)
SAX処理は、イベントフローの特性に基づいています。分析ではなく、すべてのデータが処理されるのを待つよりも、すぐに始めることができます。何もデータがメモリに格納されていないので、さらに、アプリケーションので単に、読み出しデータ内のデータをチェックします。これは、大規模な文書の大きな利点です。実際には、さらに、文書全体を構文解析することなく、アプリケーション、解析一定の条件が満たされたときに停止することができます。XML文書の解析にサックスアナライザは、一連のイベントをトリガーする、アプリケーションは、イベントのタイミングがトリガされるため、そうサックスアナライザは、XMLのようなものを提供し、イベントハンドラを使用したXML文書へのアクセスを可能に文書シーケンシャルアクセス機構は、戻って再処理ではない部分のために分析されている。加えて、それはバイトストリームのXML文書2個の同時アクセスタグ、達成にサックスアナライザが、順次チェックを扱うことができません現在のバイトは、XML構文コンプライアンスのXML文法チェックの一部であり、対応するイベントをトリガする。イベントハンドラ自体のために、アプリケーション自体によって達成されるかどうかを決定する。SAXパーサは、イベントベースのモデルを使用して、それがXML文書の解析時に発見したときのラベルを開発する方法を伝えるために、コールバックメソッドをアクティブにすることができます与えられたタグは、発見されたとき、一連のイベントをトリガすることができます。
利点:
①、すべてのデータがロードされるのを待たずにすぐにアクセスすることができます。
②、データを読み込むときにのみデータをチェックし、メモリに格納する必要はありません
③、全データをメモリにロードする必要はありません、それはより少ないメモリを占有し
④、複数のハンドラを登録することができ、文書の内容を解析するために使用することができ、DTDの制約など。
短所:
①、(など、親/子関係を維持するなど)は、タグの独自のプログラムを担当するロジックを処理するアプリケーション、より複雑な文書より複雑な手続きが必要です。
ドキュメントレベルを見つけることができない②、一方向のナビゲーションは、データが同時に同じ文書の異なる部分にアクセスすることは困難であり、それはXPathをサポートしていません。
③はなく、ランダムアクセスのXML文書、修正XMLをサポートしていない場所。
適用されます:文書が大きかった、文書データのみを読み取る必要があります。
3、JDOM(Javaベースのドキュメント・オブジェクト・モデル)
JDOMは具象クラスではなく、インターフェースを使用して、純粋なJava APIのXMLの処理です。JDOMは、ツリーを走査するために持っているJavaのSAXのルールがあります。
JDOMとDOMは主に二つの異なる側面です。まず、JDOMは、インタフェースを使用せずに、具象クラスのみを使用しました。これは、いくつかの方法でAPIを簡素化するだけでなく、柔軟性を制限されます。第二に、コレクションクラスのAPI広範な使用、すでにこれらのクラスに精通しているJava開発者の使用を簡素化します。
JDOM自体は、パーサーが含まれていません。(それは入力としてDOM構造の前にあってもよい)多くの場合、解析および検証入力XML文書にSAX2パーサーを使用しています。これは、JDOMはSAX2イベントストリーム、DOMモデルまたはXMLテキストドキュメントとして表現出力するコンバータの数が含まれています。JDOMは、Apacheオープンソースライセンスの変種の下でリリースされます。
利点:
①、特定のクラスの代わりに、インタフェースの使用、DOM APIを簡素化します。
②、Java開発者のための便利なJavaのコレクションクラスの広範な使用。
短所:
①、文書のメモリより大きく扱うことができません。
②、APIはシンプルで、何より良い柔軟性がありません
4、DOM4J(Java用のドキュメント・オブジェクト・モデル)
DOM4Jの成果が、当初は完全に独立した開発を表しますが、それは、JDOMのインテリジェントなブランチです。これは、統合されたXPath、XMLスキーマのサポート、および大規模な文書やイベントベースのドキュメントのストリームを処理するためのサポートを含む基本的なXML文書表現を超えた多くの機能が組み込まれています。また、ドキュメントを構築するオプションがDOM4J APIおよび標準のDOMインタフェースを介して並列にアクセスしていることを示しています。2000年の後半から始まって、それは開発が進められています。
これらすべての機能、DOM4Jの使用インターフェイスと抽象基本クラスのメソッドをサポートします。コレクションAPIのクラスDOM4J広範囲に使用しますが、多くの場合、それはより良い性能以上の直接符号化方法を可能にするための代替方法の数を提供します。直接的な利益は、DOM4Jが、より複雑なAPIの費用を支払うということですが、それは、JDOMよりもはるかに大きな柔軟性を提供しています。
柔軟性、XPathの統合や大規模なドキュメント処理をターゲットに、DOM4Jの目標を追加し、JDOMは同じです:Java開発者の使いやすさと直感的な操作のために。また、JDOMのソリューションは、自然の中ですべてのJava / XMLの問題に対処するための目標を達成するよりも、より完全なものを目指しています。この目的が完了すると、それはあまり正しくないアプリケーションの動作を防ぐJDOMよりも強調されています。
DOM4Jは、優れた性能、パワフルで非常に使いやすい機能を備えた、非常に、非常に良いのJavaのXML APIである、それはまた、ソフトウェアのオープンソースです。今、あなたはXMLを読み書きするために使用DOM4Jであり、より多くのJavaソフトウェアを見ることができ、特に言及する価値があるにも日もJAXM DOM4Jを使用していることです。
利点:
①、広範な使用のJavaコレクションクラス、便利なJava開発者、パフォーマンスを改善するためのいくつかの代替方法を提供します。
②、XPathをサポートしています。特に高速のノードを探します
③、高い柔軟性。
短所:
①、インターフェースの使用の多くは、複雑で困難なAPIを理解します。
②、移植性差。
注:XPathは、XMLドキュメントの言語での発見情報です。
比較:
1は、DOM4J最高のパフォーマンス、でも日もJAXM DOM4Jを使用します。有名なHibernateのような多くのオープンソースプロジェクトDOM4Jの広範な使用は、また、XML設定ファイルを読み込むためにDOM4Jを使用します。あなたは移植性を考慮していない場合は、DOM4Jを使用しました。
2、試験が、携帯時の性能試験、メモリオーバーフロー10M文書中JDOMとDOMパフォーマンスの低下。小さな文書の例では、使用DOMとJDOMを検討する価値がある。JDOMの開発者が公式リリースの問題の前に、パフォーマンスに焦点を当てることを期待していることを示しているが、パフォーマンスの観点から、それはそれをお勧めしませんが。また、DOMは、まだ非常に良い選択です。DOM実装は、広くさまざまなプログラミング言語で使用されています。それ正式にW3C勧告は、(非標準のJavaベースのモデルではなく)、そのプロジェクトの特定の種類の中でも(例えばJavaScriptのDOMでの使用として)それを必要とするかもしれないのでそれはまた、他の多くのXMLベースの標準規格に関連しています。
イベント駆動型 - 3、SAXのパフォーマンスは、その具体的な分析方法に依存している、優れています。SAXは、今後XMLストリームを検出したが、(もちろん、XMLストリームが読み込まれるときに、文書の部分がメモリ内に隠されているがあります)メモリにロードされていません。
要約すると:あなたはXML文書大きな推奨DOM4Jの移植性の問題を考慮していない場合、あなたはタイムリーな治療を必要とせずにデータを保存する必要がある場合はSAXとみなされ、XMLドキュメントが小さい場合には、JDOMの使用をすることをお勧めします。
例
最初のステップ:student.xmlファイルの確立、解析的に上記の4つの私達の比較分析にこのファイル。
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>Tom</name>
<age>11</age>
</student>
<student>
<name>Bob</name>
<age>22</age>
</student>
<student>
<name>Marry</name>
<age>23</age>
</student>
</students>
DOM解析(JDKのjarパッケージが既に追加なしインポートが付属しています!)
import java.io.FileOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DomParser{
/**
* 解析器读入整个文档,然后构建一个驻留内存的树结构,
* 该方法返回 Document 对象,然后我们可以通过 这个对象来操作文档
*/
public Document getDocument(String fileName) throws Exception{
//1.创建解析工厂
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//2.得到解析器
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
//3.得到文档对象
Document document = dBuilder.parse(fileName);
return document;
}
//读取xml文档中的数据
public void read(String fileName) throws Exception{
//获取 Document 对象
Document document = new DomParser().getDocument(fileName);
//获取<name></name>的节点
NodeList nameNode = document.getElementsByTagName("name");
//获取<name sex="xxx"></name>节点的sex属性
Element element = (Element) document.getElementsByTagName("name").item(0);
System.out.println(element.getAttribute("sex"));//xxx
for(int i = 0 ; i < nameNode.getLength() ;i++){
System.out.println(nameNode.item(i).getTextContent());
}
/**结果为
* Tom
* Bob
* Marry
*/
//获取文档的根元素对象
Element rootElementName = document.getDocumentElement();
System.out.println(rootElementName.getNodeName()); //students
//得到根节点
Node root = document.getElementsByTagName(rootElementName.getNodeName()).item(0);
list(root);
}
//打印所有标签
private void list(Node root) {
if(root instanceof Element){
System.out.println(root.getNodeName());
}
NodeList list = root.getChildNodes();
for(int i = 0 ; i < list.getLength() ; i++){
Node child = list.item(i);
list(child);
}
}
//向 xml 文件中增加节点和属性
public void add(String fileName) throws Exception{
//获取 Document 对象
Document document = new DomParser().getDocument(fileName);
//创建节点
Element sex = document.createElement("sex");
sex.setTextContent("男");
//把创建的节点添加到第一个<student></student>标签上
Element student = (Element) document.getElementsByTagName("student").item(0);
student.appendChild(sex);
//在<name></name>中增加属性 <name address="xxx"></name>
Element name = (Element) document.getElementsByTagName("name").item(0);
name.setAttribute("address", "xxx");
//把更新后的内存写入xml文档中
TransformerFactory tfFactory = TransformerFactory.newInstance();
Transformer tFormer = tfFactory.newTransformer();
tFormer.transform(new DOMSource(document),
new StreamResult(new FileOutputStream("src/student.xml")));
}
//向 xml 文件中删除节点和属性
public void delete(String fileName) throws Exception{
//获取 Document 对象
Document document = new DomParser().getDocument(fileName);
//得到要删除的第一个<name></name>节点
Element name = (Element) document.getElementsByTagName("name").item(0);
//得到要删除的第一个<name></name>节点的父节点
//Element student = (Element) document.getElementsByTagName("student").item(0);
//student.removeChild(name);
//上面两步可以简写为
name.getParentNode().removeChild(name);
//在<name></name>中删除属性 <name address="xxx"></name>
name.removeAttribute("address");
//把更新后的内存写入xml文档中
TransformerFactory tfFactory = TransformerFactory.newInstance();
Transformer tFormer = tfFactory.newTransformer();
tFormer.transform(new DOMSource(document),
new StreamResult(new FileOutputStream("src/student.xml")));
}
//向 xml 文件中更新节点和属性
public void update(String fileName) throws Exception{
//获取 Document 对象
Document document = new DomParser().getDocument(fileName);
//得到要删除的第一个<name></name>节点
Element name = (Element) document.getElementsByTagName("name").item(0);
//在<name></name>中更新属性 <name address="xxx"></name>为<name address="yyy"></name>
name.setAttribute("address", "yyy");
//更新name节点的文字为VAE,即<name>vae</name>
name.setTextContent("vae");
//把更新后的内存写入xml文档中
TransformerFactory tfFactory = TransformerFactory.newInstance();
Transformer tFormer = tfFactory.newTransformer();
tFormer.transform(new DOMSource(document),
new StreamResult(new FileOutputStream("src/student.xml")));
}
}
SAX解析(JDKのjarパッケージが既に追加なしインポートが付属しています!)
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class SaxParser{
public static void main(String[] args) throws Exception {
//1.创建解析工厂
SAXParserFactory spFactory = SAXParserFactory.newInstance();
//2.得到解析器
SAXParser sParser = spFactory.newSAXParser();
//3.得到读取器
XMLReader xmlReader = sParser.getXMLReader();
//4.设置内容处理器
xmlReader.setContentHandler(new TagDefaultHandler());
//5.读取 XML 文档内容
xmlReader.parse("src/student.xml");
}
}
//第一种方法:继承接口ContentHandler 得到 XML 文档所有内容
class ListHandler implements ContentHandler{
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.println("<"+qName+">");
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch,start,length));
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("</"+qName+">");
}
@Override
public void setDocumentLocator(Locator locator) {
}
@Override
public void startDocument() throws SAXException {
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
}
@Override
public void skippedEntity(String name) throws SAXException {
}
}
//使用继承类 DefaultHandler 更好
class TagDefaultHandler extends DefaultHandler{
//当前解析的是什么标签
private String currentTag;
//想获得第几个标签的值
private int tagNumber=0;
//当前解析的是第几个标签
private int currentNumber=0;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag = qName;
//当前解析的name 标签是第几个
if("name".equals(currentTag)){
currentNumber++;
System.out.println(currentNumber);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//打印所有name标签的值
if("name".equals(currentTag)){
System.out.println(new String(ch,start,length));
}
//想获得 第二个name标签的值
tagNumber = 2;
if("name".equals(currentTag)&¤tNumber==tagNumber){
System.out.println(new String(ch,start,length));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentTag = null;
}
}
SAXはアンドリュースを解決する文字化け
public static String getStringByUrl(String getUrl) {
// String getUrl =
StringBuffer sb = new StringBuffer();
InputStreamReader isr = null;
BufferedReader br = null;
try {
URL url = new URL(getUrl);
URLConnection urlConnection = url.openConnection();
urlConnection.setReadTimeout(60000);
urlConnection.setAllowUserInteraction(false);
/*isr = new InputStreamReader(url.openStream());*/
isr = new InputStreamReader(url.openStream(),Charset.forName("UTF-8"));
br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (br != null) {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return sb.toString();
}
DOM4Jの決意
JARパッケージのダウンロードリンク:http://pan.baidu.com/s/1b5L9AA パスワード:wg2l
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
public class DOM4JParser {
//读取第二个<name><name>
@Test
public void read() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/student.xml"));
//得到根节点
Element root = document.getRootElement();
//得到第二个<student><student>节点
Element student = (Element)root.elements("student").get(1);
//获取<name><name>中间的值
String value = student.element("name").getText();
System.out.println(value);//Bob
//获取<name sex="xxx"><name>中间的sex值
String sexValue = student.element("name").attributeValue("sex");
System.out.println(sexValue);//xxx
}
//增加节点
@Test
public void add() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/student.xml"));
Element student = document.getRootElement().element("student");
student.addElement("schoolName").setText("湖北");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/student.xml"),format);
writer.write(document);
writer.close();
}
//删除节点
@Test
public void delete() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/student.xml"));
Element student = (Element)document.getRootElement().elements("student").get(1);
student.element("schoolName").setText("湖南");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/student.xml"),format);
writer.write(document);
writer.close();
}
//修改节点
@Test
public void update() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/student.xml"));
Element student = document.getRootElement().element("student");
Element schoolName = student.element("schoolName");
schoolName.getParent().remove(schoolName);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/student.xml"),format);
writer.write(document);
writer.close();
}
}
XPathのはじめに:
DOM4JはXPathをサポートしているため、XPathが、それは何ですか?
XPathは、XMLドキュメントの言語での発見情報です。XML文書またはノードのセット内のノードを選択するために、パス式を使用します。私たちは、従来のコンピュータのファイルシステムに表示これらのパス式と式は非常に似ています。
私たちは、どのような使い方の例を見て:
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class XPathParser {
public static void main(String[] args) throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/student.xml"));
//得到第一个 name 节点的值
String nameValue = document.selectSingleNode("//name").getText();
System.out.println(nameValue); //Tom
//得到所有 name 节点的值
List<Node> nameValues = document.selectNodes("//name");
for(Node obj : nameValues){
System.out.println(obj.getText());//Tom Bob Marry
}
}
}