[英]How should I use line number and column number to get element in XML in JAVA
嗨,我正在使用JAXB和元組/解組架構驗證。 我有一個XML文件和XSD架構用於驗證。 代碼如下:
Validation.java
try{
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("./src/main/resources/validation.xsd"));
JAXBContext jc = JAXBContext.newInstance(AddCustomer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(new MyValidationEventHandler());
AddCustomer addCustomer_Validation= (AddCustomer) unmarshaller.unmarshal(new File("./src/main/resources/AddCustomer.xml"));
logger.info("AddCustomer passed validation.");
} catch(UnmarshalException ex) {
logger.info("linked ex: " + ex.getLinkedException().toString());
String str = ex.getLinkedException().toString();
int lineNumberIndex = str.indexOf("lineNumber:");
int lineNumber = Integer.parseInt(str.substring(lineNumberIndex+12,lineNumberIndex+13));
logger.info("lineNumber:" +lineNumber);
int columnIndex = str.indexOf("columnNumber:");
int columNumber = Integer.parseInt(str.substring(columnIndex+14,columnIndex+16));
logger.info("columnNumber: " + columNumber);
}
一些XML文件是這樣的:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AddCustomer xmlns="http://...">
<Customer>
<DirectoryInformation>
<PortalID>32 4 5</PortalID>
<AccountID>2732</AccountID>
從上面的代碼中,我可以驗證XML對XSD是否有效。 記錄器文件是這樣的:
INFO [main] Validation- linked ex: org.xml.sax.SAXParseException; systemId: file:/C:.../src/main/resources/AddCustomer.xml; lineNumber: 5; columnNumber: 41; cvc-pattern-valid: Value '32 4 5' is not facet-valid with respect to pattern '[ !-~]*' for type 'an..35'.
INFO [main] Validation- lineNumber: 5
INFO [main] Validation- columnNumber: 41
驗證是正確的,並且在xml文件中,PortalID的值對XSD架構無效,並且日志文件可以告訴我該位置是“ lineNumber 5和ColumNumber 41”,這正是PortalID的位置。
但是我想要的是使用此lineNumber 5和ColumNumber 41來打印出XML中的元素PortalID無效。 有什么辦法嗎? 非常感謝!
要獲取已解析的最后一個元素的名稱,可以放置一個自定義的ContentHandler,它記錄SAXParser和JAXB處理程序之間的最后一個元素。
為此,您必須使用SAXSource並創建擴展XMLFilterImpl的自定義XMLFilter實現。
SAXSource
傳遞給Unmarshaller
而不是File
並在SAXSource
配置XMLReader
。 使用指定的驗證SAX2.0解析器的客戶端從javax.xml.transform.sax.SAXSource解組中對此進行了解釋。 不要像Javadoc鏈接代碼中那樣用“真正的” XMLReader
實現配置SAXSource
,而是使用包裝“真正的” XMLReader
的自定義XMLFilter。
XMLReader xmlReader = saxParser.getXMLReader(); RecordingXMLFilter xmlFilter = new RecordingXMLFilter(xmlReader); SAXSource source = new SAXSource(xmlFilter, new InputSource(new FileInputStream(new File("./src/main/resources/AddCustomer.xml")));
定制過濾器RecordingXMLFilter
可以是:
private static final class RecordingXMLFilter extends XMLFilterImpl { String lastElement; private RecordingXMLFilter(XMLReader parent) { super(parent); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { lastElement = qName; super.startElement(uri, localName, qName, attributes); } }
xmlFilter.lastElement
獲取解析的最后一個元素的QName。 BTW要以這種方式獲取行號,消息在不同的區域可能會有所不同,或者在版本之間會有所不同。
try
{
..........
}
catch(UnmarshalException ex) {
Throwable linked = ex.getLinkedException();
if (linked instanceof SAXParseException)
{
SAXParseException t = (SAXParseException) linked;
int lineNumber = t.getLineNumber();
int columNumber = t.getColumnNumber();
logger.info("lineNumber:" +lineNumber);
logger.info("columnNumber: " + columNumber);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.