如何使用 statx 解析器识别空 xml 标记

Posted

技术标签:

【中文标题】如何使用 statx 解析器识别空 xml 标记【英文标题】:how to identify the empty xml tag using statx parser 【发布时间】:2013-11-28 14:12:20 【问题描述】:

我想在解析这个 XML 内容时识别标签。我们有 isStartElement() 或 isEndElement() 之类的方法。但这并不属于这两个类别。请帮助我。如何处理这种标签。

代码:

 import java.io.StringReader;
 import java.util.Hashtable;
 import java.util.Iterator;

 import javax.xml.stream.Location;
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.events.EndElement;
 import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;

 public class Sample 

public static void main(String[] args) 
    String xPath = "HAI/ONE";       
    String xml = "<HAI><ONE/></HAI>";
    try 
        System.out.println(getValueByXPath(xml,xPath));

     catch (Exception e) 
        e.printStackTrace();
    




     
 public  String getValueByXPath(String xmlString, String xPathString)
    String value = "";
    String tagName = null;
    int index = 2;
    int hashIndex = 1;
    int tagBalance = 0;
    String tagIndex = null;
    String[] tagIndexArr = null;
    Hashtable<Integer,String> xPathHashtable = null;

    XMLInputFactory xmlInputFactory;
    XMLEventReader xmlEventReader;
    try            
        xmlInputFactory = XMLInputFactory.newInstance();
        xmlInputFactory.setProperty  
          (XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,Boolean.TRUE);       
        xmlInputFactory.setProperty
          (XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,Boolean.FALSE);
        xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, 
           Boolean.FALSE);   
        xmlEventReader = xmlInputFactory.createXMLEventReader(new StringReader
           (xmlString));

        //Split XPath 
        xPathHashtable = splitXPath(xPathString);

        tagIndex = xPathHashtable.get(hashIndex);
        tagIndexArr = tagIndex.split("=");
        tagName = tagIndexArr[0];
        index = Integer.parseInt(tagIndexArr[1])+1;

        while (xmlEventReader.hasNext())  
            XMLEvent e = xmlEventReader.nextEvent(); 

            if(tagBalance < 0 )
                return "";
            

            if(index==1 && e.isCharacters())
                value = e.asCharacters().getData();
                hashIndex++;
                tagIndex = xPathHashtable.get(hashIndex);
                if(tagIndex == null)break;
                tagIndexArr = tagIndex.split("=");
                tagName = tagIndexArr[0];
                index = Integer.parseInt(tagIndexArr[1])+1;
                tagBalance = 0;
                System.out.println(tagName+"tag"+index);

            
            if (e.isStartElement())                    
                StartElement startElement = e.asStartElement(); 
                if(tagName.equalsIgnoreCase(startElement.getName
                                                  ().getLocalPart()))
                    index--;
                    tagBalance++;
                
               

            if (e.isEndElement())  

                EndElement endElement = e.asEndElement();

                if(tagName.equalsIgnoreCase(endElement.getName
                                                 ().getLocalPart()))                       
                    tagBalance--;
                                        
            
        

    catch(Exception e)
        e.printStackTrace();
    
    return value;


public  Hashtable<Integer,String> splitXPath(String xPath)

    Hashtable<Integer,String> xPathHashtable = null;
    String[] xPathSplit = null;
    int hashIndex = 0;

    int index = 1;
    String tag= null;
    try
        xPathHashtable = new Hashtable<Integer,String>();
        xPathSplit = xPath.split("[\\[\\]/]");

        for(int i=0;i<xPathSplit.length;i++)

            if(xPathSplit[i].isEmpty()) continue;

            try
                index = Integer.parseInt(xPathSplit[i]);
            catch(Exception e)
                tag = xPathSplit[i];
                index = 1;
                hashIndex++;
            
            xPathHashtable.put(hashIndex, tag+"="+index);               
        

    catch(Exception e)
        e.printStackTrace();
    

    return xPathHashtable;

 

我正在使用 Stax 解析器模拟 XPath 场景。

【问题讨论】:

【参考方案1】:

我遇到了和你一样的问题,在任何地方都找不到解决方案。

你想做的就是使用

xmlEventReader.peek().isEndElement()  

并随心所欲地处理。 peek() 不会像 .nextEvent() 那样移动元素。

【讨论】:

以上是关于如何使用 statx 解析器识别空 xml 标记的主要内容,如果未能解决你的问题,请参考以下文章

使用 SAX 解析器解析自关闭 XML 标记时遇到问题

使用DOM解析器解析XML文档,每个标记包含多个元素

需要 XML 解析器错误开始标记

对象解析

使用 Java 解析 HTML 标签

解析器与词法分析器和 XML