2017-06-15 24 views
0

當xml輸入作爲輸入流提供給SAX解析器並且其中一些xml元素爲空時,那麼解析器的字符方法不是 調用並獲得不同的結果。當xml輸入作爲流並且某些xml元素爲空時,SAX解析器無法正常工作

例如,

XML輸入:

<root> 
    <salutation>Hello Sir</salutation> 
    <userName /> 
    <parent> 
     <child>a</child> 
    </parent> 
    <parent> 
     <child>b</child> 
    </parent> 
    <parent> 
     <child>c</child> 
    </parent> 
    <success>yes</success> 
    <hoursSpent /> 
</root> 

解析器實現:

public class MyContentHandler implements ContentHandler { 

private String salutation; 
private String userName; 
private String success; 
private String hoursSpent; 
String tmpValue=""; 

public void endElement(String uri, String localName, String qName) throws SAXException { 
if ("salutation".equals(qName)) { 
     userName=tmpValue; 
     } 
}else 
if ("userName".equals(qName)) { 
     userName=tmpValue; 
     } 
}else 
if ("success".equals(qName)) { 
     success=tmpValue; 
     } 
}else 
if ("hoursSpent".equals(qName)) { 
     hoursSpent=tmpValue; 
     } 
} 


public void characters(char[] ch, int begin, int length) throws SAXException { 

    tmpValue = new String(ch, begin, length).trim(); 
} 

主程序:

public class MainProgram{ 

    public static void main(String[] args) throws Exception { 
    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 
    SAXParser saxParser = saxParserFactory.newSAXParser(); 

    XMLReader xmlReader = saxParser.getXMLReader(); 

    MyContentHandler contentHandler = new MyContentHandler(xmlReader); 
    xmlReader.setContentHandler(contentHandler); 

    String input = "<root><salutation>Hello Sir</salutation><userName /><parent><child>a</child></parent><parent><child>b</child></parent><success>yes</success><hoursSpent /></root>"; 
    InputStream stream = new ByteArrayInputStream(input.getBytes()); 
    xmlReader.parse(new InputSource(stream)); 
    System.out.println(contentHandler.getUserName()); //prints Hello sir instead of null 
System.out.println(contentHandler.getHoursSpent); //prints yes instead of null 

如果空的xml元素,而不打開指定的ND如下靠近元件,

<userName /> 

代替<userName></userName>,那麼不執行該處理程序類的字符()方法和錯誤的值被設置。只有當我使用input xml作爲輸入流時纔會出現此問題。請幫我解決這個問題

+0

爲什麼不直接重寫[startElement](http://docs.oracle.com/javase/8/docs/api/org/xml/sax/ContentHandler.html#startElement-java.lang.String-java.lang 。String-java.lang.String-org.xml.sax.Attributes-)並讓該方法將'tmpValue'重置爲空字符串? – VGR

+0

是的,它按預期工作 – pradeep

回答

3

解析器的行爲與指定的完全一樣,它是你的代碼是錯誤的。

通常,解析器在開始標記和相應的結束標記之間的characters()方法上進行零對多調用。您需要在startElement()中初始化一個空緩衝區,以字符()附加緩衝區,然後使用endElement()中的累加值。如果解析器將文本分解爲多個調用,那麼經常發生如果(a)存在,那麼您不但會得到錯誤的結果,而且還會得到錯誤的結果是文本中的實體引用,或者(b)文本非常長,或者(c)文本恰好跨越在單獨的read()調用中從輸入流中讀取的兩個塊。