XmlParserとHtmlParser


よく使われるXmlやHtmlで解決するが、実際にはこの分野にも非常に良い解決策がある.
相対的に今各种のオープンソースXmlの解析机能は比较的に豊富で、メカニズムも比较的に柔软で、しかし彼の机能は比较的に完璧で、やることは比较的に多いため、性能の方面も少し遅いです;また、Xmlは生まれながらにして厳格なフォーマットがあるため、問題は大きくありませんが、Htmlファイルの内容は玉石混交で、閉鎖ラベルが欠けているサイトもあり、最初は大文字、閉鎖は小文字など、規範を厳格に守っていない場合、Dom構造さえ正しく理解できず、データキャプチャプログラムにとって、正確性に深刻な影響を及ぼします.
また,重要な問題はデータ遍歴であり,一般にデータ遍歴ではオープンソースフレームワークが性能を十分に最適化していないため,高速検索を行うにはプログラム拡張が必要である.そのため、私はXmlParserとHtmlParserのセットを作成し、データ検証の面で削除し、データ検証をサポートせず、フォールトトレランスの面で拡張し、Html解決の際、フォーマットが正しくなくても、多くの場合、正しい結果を返すことができます.最悪の場合もDomを解決できるが,Dom構造は必ずしも正確ではなく,クラッシュや解析異常の問題は起こらない.
もう1つは、<中国語属性1="1"属性2="b"/>など、簡体字中国語ラベルのサポート機能です.
OK、余計なことは言わないで、呼び出しコードを見てください.
XmlStringParser parser = new XmlStringParser();
XmlDocument xmlDocument = parser.parse("<aa a=\"1\"><!--aa --><a a=\"aa\"></a></aa>");
上でxmlを解析しました.
HtmlStringParser parser = new HtmlStringParser();
HtmlDocument xmlDocument = parser.parse("<aa a=\"1\"><!--aa --><a a=\"aa\"></a></aa>");

上はhtmlを解析しました.
XmlとHtmlは統一されたインタフェースを使用しているので、Xml解析ができ、Htmlも同じです.
解析したノードは,いずれも次のインタフェースを実現しているので,遍歴面でも非常に便利である.
public interface Node<T extends Node<T>> extends ForEachProcessor<T> {
	/**
	 *            
	 * 
	 * @return StringBuffer
	 */
	void getHeader(StringBuffer sb);

	/**
	 *      
	 * 
	 * @param name
	 * @return
	 */
	List<T> getSubNodes(String name);

	/**
	 *       
	 * 
	 * @param content
	 */
	void addContent(String content);

	/**
	 *       
	 * 
	 * @param name
	 */
	void setNodeName(String name);

	/**
	 *       
	 * 
	 * @return StringBuffer
	 */
	void getFooter(StringBuffer sb);

	/**
	 *      
	 * 
	 * @return T
	 */
	T getRoot();

	/**
	 *       
	 * 
	 * @param parent
	 */
	void setParent(T parent);

	/**
	 *       
	 * 
	 * @return
	 */
	String getNodeName();

	/**
	 *       
	 * 
	 * @return
	 */
	T getParent();

	/**
	 *       
	 * 
	 * @return
	 */
	StringBuffer getBody();

	/**
	 *     
	 * 
	 * @param stream
	 * @throws IOException
	 */
	void write(OutputStream stream) throws IOException;

	/**
	 *       
	 * 
	 * @return
	 */
	NodeType getNodeType();

	/**
	 *     
	 * 
	 * @param attributeName
	 * @return
	 */
	String getAttribute(String attributeName);

	/**
	 *     
	 * 
	 * @param attributeName
	 */
	void removeAttrivute(String attributeName);

	/**
	 *      
	 * 
	 * @param attributeName
	 * @param value
	 */
	void setAttribute(String attributeName, String value);

	/**
	 *     
	 * 
	 * @param node
	 *                  
	 * @return       ,   node  ,    null
	 */
	T addNode(T node);

	/**
	 *     
	 * 
	 * @param node
	 * @return      ,          node  ,   null
	 */
	T removeNode(T node);

	/**
	 *       
	 * 
	 * @param nodeName
	 * @return
	 */
	List<T> removeNode(String nodeName);

	/**
	 *     
	 * 
	 * @return
	 */
	String getContent();

	/**
	 *   StreamBuffer
	 * 
	 * @return
	 */
	StringBuffer toStringBuffer();

	/**
	 *     
	 * 
	 * @param content
	 */
	void setContent(String content);

	/**
	 *      
	 * 
	 * @return
	 */
	Map<String, String> getAttributes();

	/**
	 *      
	 * 
	 * @return
	 */
	List<T> getSubNodes();

	/**
	 *      
	 * 
	 * @return
	 */
	boolean isSingleNode();

	/**
	 *        
	 * 
	 * @return
	 */
	boolean isCaseSensitive();

	/**
	 *            
	 * 
	 * @param name
	 * @return
	 */
	String getCaseSensitiveName(String name);

	/**
	 *        
	 * 
	 * @return
	 */
	String getPureText();
}
インタフェースが膨大すぎるのを避けるために、フォーマットされた処理を独立した構造に置いて処理する.
public interface NodeFormater<E extends Node<E>, T extends Document<E>> {
	/**
	 *      
	 * 
	 * @param doc
	 * @return String
	 */
	String format(T doc);

	void setEncode(String encode);

	/**
	 *      、            
	 * 
	 * @param doc
	 * @param out
	 * @return void
	 * @throws IOException
	 */
	String format(E node);

	void format(T doc, OutputStream out) throws IOException;

	void format(E node, OutputStream out) throws IOException;
}
入力をフォーマットするには、次のコードでいいです.
HtmlDocument doc= new XmlStringParser().parse("<html  =' '><head><title>aaa</title></head></html>");
HtmlFormater f = new HtmlFormater();
System.out.println(f.format(doc));
の出力結果は次のとおりです.
<html  =" ">
  <head>
    <title>
      aaa
    </title>
  </head>
</html>
では、解析およびフォーマットおよび遍歴が示されており、検索を参照してください.
まず60*60*60を構築し,3層のDom構造,すなわち現在21,6000個のDomノードがある.
XmlNode node = new XmlNode("root");
for (int i = 0; i < 60; i++) {
	XmlNode a = node.addNode(new XmlNode("a" + i));
	for (int j = 0; j < 60; j++) {
		XmlNode b = a.addNode(new XmlNode("b" + j));
		for (int k = 0; k < 60; k++) {
			b.addNode(new XmlNode("c" + k));
		}
	}
}
その後、ノード検索を行い、10000回のノードフィルタリングを2つの方法で行います.
public void testSpeed() {
	long t21 = System.currentTimeMillis();
	QuickNameFilter quick = new QuickNameFilter(node);
	long t22 = System.currentTimeMillis();
	System.out.println("quick     " + (t22 - t21));
	long t1 = System.currentTimeMillis();
	String nodeName = null;
	for (int x = 0; x < 10000; x++) {
		nodeName = quick.findNode("b6").toString();
	}
	long t2 = System.currentTimeMillis();
	System.out.println("QuickNameFilter  " + (t2 - t1));
}

public void testSpeed1() {
	long t21 = System.currentTimeMillis();
	FastNameFilter fast = new FastNameFilter(node);
	long t22 = System.currentTimeMillis();
	System.out.println("fast     " + (t22 - t21));
	long t1 = System.currentTimeMillis();
	String nodeName = null;
	for (int x = 0; x < 10000; x++) {
		nodeName = fast.findNode("b6").toString();
	}
	long t2 = System.currentTimeMillis();
	System.out.println("FastNameFilter  " + (t2 - t1));
}

時間のかかる状況を見てみましょう.
quick     385
QuickNameFilter  376
fast     122
FastNameFilter  330
fastの初期化時間と検索時間が最も速いことがわかります.quickの初期化時間は検索時間に比べて遅い.ただし、216000ノードで10000回検索するのにかかる時間であることに注意してください.
では、伝統的な方法で試してみましょう.一般的なオープンソースの方法もこのレベルには違いません.
public void testSpeed2() {
	long t11 = System.currentTimeMillis();
	NameFilter filter = new NameFilter(node);
	long t12 = System.currentTimeMillis();
	System.out.println("Name     " + (t12 - t11));
	long t1 = System.currentTimeMillis();
	String nodeName = null;
	for (int x = 0; x < 10; x++) {
		nodeName = filter.findNode("b6").toString();
	}
	long t2 = System.currentTimeMillis();
	System.out.println("NameFilter  " + (t2 - t1));
}
実行結果:
Name     12
NameFilter  83
しかし、彼のクエリー回数は10回で、10000回になると83000 ms、つまり83秒以上になることに注意してください.Fastフィルタリング方式と680倍の差があります.
小結:我々が実現したXmlおよびHtml Parserは確かに独自の利点(学習コストが低く、HtmlとXmlの解析方法が一致し、フォーマット出力、コンパクト出力、フォールトトレランス性、クエリー効率が高いなど)があり、不足(DTD、XSDチェックをサポートしていない)もあり、チェックを必要としないシーンではフォールトトレランス性がよく、フィルタ性能が高いシーンでは、非常に優位である.