dom4j如何獲取節點的行數,列數
在使用dom4j解析xml檔案時,可能會對一些節點做檢測,判斷是否符合schema,對一些不符合的節點要作出提示。為了使作出的提示更友好,還需要指出錯誤在哪裡。但是dom4j並沒有提供相關的功能,或者說這個功能隱藏的很深。搜尋了一下,發現這個問題的答案很少。我在一個mail(https://www.mail-archive.com/[email protected]/msg02769.html)中得到了提示,摸索了出來,巨麻煩。該mail提到了主要的過程:
org.xml.sax.Locator locator = new …; DocumentFactory documentFactory = new DocumentFactoryWithLocator(locator); SAXContentHandler contentHandler = new SAXContentHandler(documentFactory); contentHandler.setDocumentLocator(locator); org.xml.sax.XMLReader reader = …; reader.setContentHandler(contentHandler ); reader.parse(…); Document document = contentHandler.getDocument();
在DocumentFactory中:
public Element createElement(QName qname) {
ElementWithLocation element = new ElementWithLocation (qname);
element.setLocation(locator.getLineNumber(),
locator.getColumnNumber());
return element;
}
方向是對的,但是按照這個方法做出來,卻得不到正確的結果。原因是,SAXReader中的XMLReader在呼叫parse方法時,會重新賦值locator,把我傳進去的locator覆蓋掉了,這樣在DocumentFactory就不是XMLReader中的locator。dom4j使用的XMLReader是org.apache.xerces中的SAXParser,該類繼承了AbstractSAXParser,在AbstractSAXParser中有一個方法:
public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext, Augmentations augs) throws XNIException { fNamespaceContext = namespaceContext; try { // SAX1 if (fDocumentHandler != null) { if (locator != null) { fDocumentHandler.setDocumentLocator(new LocatorProxy(locator)); } fDocumentHandler.startDocument(); } // SAX2 if (fContentHandler != null) { if (locator != null) { fContentHandler.setDocumentLocator(new LocatorProxy(locator)); } fContentHandler.startDocument(); } } catch (SAXException e) { throw new XNIException(e); } }
就是這個方法覆蓋了contentHandler的locator。我的做法就是在AbstractSAXParser重新賦值locator的時候獲取這個值,傳遞給DocumentFactory。
上程式碼,首先需要擴充套件原來的Element類,使之可以記錄節點的位置資訊(需要記錄Attribute等的同理)。
public class GokuElement extends DefaultElement { private int lineNum = 0, colNum = 0; public GokuElement(QName qname) { super(qname); // TODO Auto-generated constructor stub } public GokuElement(QName qname, int attrCount) { super(qname, attrCount); } public GokuElement(String name) { super(name); } public GokuElement(String name, Namespace namespace) { super(name, namespace); } public int getColumnNumber() { return this.colNum; } public int getLineNumber() { return this.lineNum; } public void setLocation(int lineNum, int colNum) { this.lineNum = lineNum; this.colNum = colNum; } }
然後,擴充套件DocumentFactory,讓factory生成我們定義的Element:
public class DocumentFactoryWithLocator extends DocumentFactory {
private Locator locator;
public DocumentFactoryWithLocator(Locator locator) {
super();
this.locator = locator;
}
@Override
public Element createElement(QName qname) {
GokuElement element = new GokuElement(qname);
element.setLocation(this.locator.getLineNumber(), this.locator.getColumnNumber());
return element;
}
@Override
public Element createElement(String name) {
GokuElement element = new GokuElement(name);
element.setLocation(this.locator.getLineNumber(), this.locator.getColumnNumber());
return element;
}
public void setLocator(Locator locator) {
this.locator = locator;
}
}
然後擴充套件SAXContentHandler:
public class GokuSAXContentHandler extends SAXContentHandler {
private DocumentFactoryWithLocator documentFactory = null;
public GokuSAXContentHandler(DocumentFactory documentFactory2, ElementHandler dispatchHandler) {
// TODO Auto-generated constructor stub
super(documentFactory2, dispatchHandler);
}
public void setDocFactory(DocumentFactoryWithLocator fac) {
this.documentFactory = fac;
}
@Override
public void setDocumentLocator(Locator documentLocator) {
super.setDocumentLocator(documentLocator);
if (this.documentFactory != null)
this.documentFactory.setLocator(documentLocator);
}
}
最後擴充套件SAXReader
public class GokuSAXReader extends SAXReader {
DocumentFactory docFactory;
Locator locator;
public GokuSAXReader(DocumentFactory docFactory) {
// TODO Auto-generated constructor stub
super(docFactory);
this.docFactory = docFactory;
}
public GokuSAXReader(DocumentFactory docFactory, Locator locator) {
// TODO Auto-generated constructor stub
super(docFactory);
this.locator = locator;
this.docFactory = docFactory;
}
@Override
protected SAXContentHandler createContentHandler(XMLReader reader) {
return new GokuSAXContentHandler(this.getDocumentFactory(), super.getDispatchHandler());
}
@Override
public Document read(InputSource in) throws DocumentException {
try {
XMLReader reader = this.getXMLReader();
reader = this.installXMLFilter(reader);
EntityResolver thatEntityResolver = super.getEntityResolver();
if (thatEntityResolver == null) {
thatEntityResolver = this.createDefaultEntityResolver(in.getSystemId());
super.setEntityResolver(thatEntityResolver);
}
reader.setEntityResolver(thatEntityResolver);
SAXContentHandler contentHandler = this.createContentHandler(reader);
contentHandler.setEntityResolver(thatEntityResolver);
contentHandler.setInputSource(in);
boolean internal = this.isIncludeInternalDTDDeclarations();
boolean external = this.isIncludeExternalDTDDeclarations();
contentHandler.setIncludeInternalDTDDeclarations(internal);
contentHandler.setIncludeExternalDTDDeclarations(external);
contentHandler.setMergeAdjacentText(this.isMergeAdjacentText());
contentHandler.setStripWhitespaceText(this.isStripWhitespaceText());
contentHandler.setIgnoreComments(this.isIgnoreComments());
reader.setContentHandler(contentHandler);
this.configureReader(reader, contentHandler);
((GokuSAXContentHandler) contentHandler).setDocFactory((DocumentFactoryWithLocator) this.docFactory);
contentHandler.setDocumentLocator(this.locator);
reader.parse(in);
return contentHandler.getDocument();
} catch (Exception e) {
if (e instanceof SAXParseException) {
// e.printStackTrace();
SAXParseException parseException = (SAXParseException) e;
String systemId = parseException.getSystemId();
if (systemId == null) {
systemId = "";
}
String message = "Error on line " + parseException.getLineNumber() + " of document " + systemId + " : "
+ parseException.getMessage();
throw new DocumentException(message, e);
} else {
throw new DocumentException(e.getMessage(), e);
}
}
}
}
重寫了read(InputSource)方法,使用我們寫的SAXContentHandler。其他簽名的read方法最後都呼叫了這個read方法。
解析檔案的程式碼:
Locator locator = new LocatorImpl();
DocumentFactory docFactory = new DocumentFactoryWithLocator(locator);
SAXReader reader = new GokuSAXReader(docFactory, locator);
Document doc = reader.read(new File("goku.xml"));
需要獲取Element資訊時:
System.out.println(((GokuElement) element).getLineNumber());
相關推薦
dom4j如何獲取節點的行數,列數
在使用dom4j解析xml檔案時,可能會對一些節點做檢測,判斷是否符合schema,對一些不符合的節點要作出提示。為了使作出的提示更友好,還需要指出錯誤在哪裡。但是dom4j並沒有提供相關的功能,或者說這個功能隱藏的很深。搜尋了一下,發現這個問題的答案很少。我在一個mai
Matlab 座標 維數,列數
A=eye(3) A(:,1) 結果: 即 尾 座標 表示 列。 A=eye(3) A(1,:) 結果: 即 次尾座標 表示 行。 三維陣列
C#中如何獲取一個二維陣列的兩維長度,即行數和列數?
int[,] array = new int[,] {{1,2,3},{4,5,6},{7,8,9}};//定義一個3行3列的二維陣列 int row = array.Rank;//獲取行數 int col = array.GetLength(1);//獲取指定維中的元 個
jsp頁面帶有多選框的grid表格,如何將勾選中的行記錄所有列數據傳送到後臺。
blank href 後臺 aaa 數據 www hue 選中 cs6 忱分慕兇釉瀑懲防慌虜敝慘緩猩http://jz.docin.com/shuvg316 帳段繁臨市杉聞壞倫捶剎空合戀http://huiyi.docin.com/ogq2843 杏燎乘安轄任凸托飯承臨
Java 數組 獲取二維數組的行數和列數
怎樣 tps lan 個數 元素 mil family 資料 object 對於Object[][] array,array.length返回行數,array[0].length返回列數,元素個數為array.length*array[0].length。 參考
Excel轉Html(十一)--POI處理Excel-獲取sheet總行數-總列數-行高-列高
獲取sheet行總數:sheet.getLastRowNum() 列總數:dataMap.get("maxColNum-" + form.getFormName() 獲取列最多的行,特別注意:sheet.getRow(0).getPhysicalNumberOfCells()不準確 行高:r
實現一個函式,列印乘法口訣表,口訣表的行數和列數自己指定, 輸入9,輸出9*9口訣表,輸入12,輸出12*12的乘法口訣表。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> int main() { int n = 0; printf("請輸入一個數:"); scanf("%d", &n);
1. 實現一個函式,列印乘法口訣表,口訣表的行數和列數自己指定, 輸入9,輸出9*9口訣表,輸出12,輸出12*12的乘法口訣表。
#define_CRT_SECURE_NO_WARNINGS1 #include<stdio.h> #include<stdlib.h> #include<math.h&
C#獲取多維陣列的行數與列數
效果圖: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.
C#獲取陣列的行數和列數
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test02 { class Program {
獲取ResultSet的行數和列數
獲取ResultSet行數時需要使用可回滾的遊標,自定義方法,獲取行數後要回滾,獲取ResultSet列數時通過ResultSetMetaData類的getColumnCount方法即可獲得。 示例程式碼: publicclass Test ...{ publicsta
多行轉多列,行數和列數不確定
原始需求,有2表如下 SQL> select * from mas; TO TOOLNAME -- ---------- 01 包裹 02 信函 03 掛號信 04 中國速遞 05 EMS 06 DHL 6 rows selected. SQL> select * from putdt; SEN
//1.實現一個函式,列印乘法口訣表,口訣表的行數和列數自己指定, //輸入9,輸出9 * 9口訣表,輸出12,輸出12 * 12的乘法口訣表。
#include<stdio.h> int print(int num) {int i = 0;for (i = 1; i <= num; i++){int j = 0;for (
如何獲取ResultSet的行數和列數
當我們執行資料庫查詢返回一個ResultSet的時候,很多情況下我們需要知道這個ResultSet的大小,即它的行數和列數。我們知道它的列數可以通過resultSet.getMetaData().getColumnCount()很容易地得到,然而,java API沒有提供直接訪問ResultSet行數的介面
獲取SQL查詢結果集中的行數和列數
轉自http://cheneyph.iteye.com/blog/477829 在Java中,獲得ResultSet的總行數的方法有以下幾種。 第一種:利用ResultSet的getRow方法來獲得ResultSet的總行數 Statement stmt = con.cre
用C語言中的函式列印乘法口訣表,行數和列數可以任意輸入
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> void print_table(int line) { int i = 0;
如何將勾選中的行記錄所有列數據傳送到後臺。
w16 user oci dpx ocs cio 數據 mcs cin 8379Kd631S柿http://huiyi.docin.com/fxa140 B12J51素N邢降1http://tushu.docin.com/bkfh0377 V7r佬1乖ZPF17裙htt
How Javascript works (Javascript工作原理) (一) 引擎,運行時,函數調用棧
由於 溢出 最好 介紹 error 堆棧溢出 git actual AR 個人總結: 這篇文章對JS底層的工作原理進行了介紹。 原文:https://blog.sessionstack.com/how-does-javascript-actually-work-part
Python獲取Nginx訪問日誌,寫入數據庫
use arc strip() for create variables *** times war #!/usr/bin/env python # coding: utf-8 # Auther:liangkai # Date:2018/6/26 11:26 # Licen
C#中二維數組的行數和列數
取數 word 二維數組 同學 定義 dimen 行數 nbsp col 最近在項目中用到二維數組,需要獲取數組的行數和列數,本以為是很簡單的一些東西,卻發現網上好多答案都是錯誤的,遂寫下隨筆,希望之後有用到的同學們能夠順利解決答案。 下面是一些關於數組的一些屬性和方法以及