Generate/get xpath from XML node java

前端 未结 8 828
清酒与你
清酒与你 2020-11-22 10:39

I\'m interested in advice/pseudocode code/explanation rather than actual implementation.

  • I\'d like to go trough xml document
8条回答
  •  无人共我
    2020-11-22 11:03

    Here is how this can be done with SAX:

    import java.util.HashMap;
    import java.util.Map;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    import org.xml.sax.helpers.DefaultHandler;
    
    public class FragmentContentHandler extends DefaultHandler {
    
        private String xPath = "/";
        private XMLReader xmlReader;
        private FragmentContentHandler parent;
        private StringBuilder characters = new StringBuilder();
        private Map elementNameCount = new HashMap();
    
        public FragmentContentHandler(XMLReader xmlReader) {
            this.xmlReader = xmlReader;
        }
    
        private FragmentContentHandler(String xPath, XMLReader xmlReader, FragmentContentHandler parent) {
            this(xmlReader);
            this.xPath = xPath;
            this.parent = parent;
        }
    
        @Override
        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
            Integer count = elementNameCount.get(qName);
            if(null == count) {
                count = 1;
            } else {
                count++;
            }
            elementNameCount.put(qName, count);
            String childXPath = xPath + "/" + qName + "[" + count + "]";
    
            int attsLength = atts.getLength();
            for(int x=0; x 0) {
                System.out.println(xPath + "='" + characters.toString() + "'");
            }
            xmlReader.setContentHandler(parent);
        }
    
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            characters.append(ch, start, length);
        }
    
    }
    

    It can be tested with:

    import java.io.FileInputStream;
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.xml.sax.InputSource;
    import org.xml.sax.XMLReader;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
    
            xr.setContentHandler(new FragmentContentHandler(xr));
            xr.parse(new InputSource(new FileInputStream("input.xml")));
        }
    }
    

    This will produce the desired output:

    //root[1]/elemA[1]='one'
    //root[1]/elemA[2][@attribute1='first]
    //root[1]/elemA[2][@attribute2='second]
    //root[1]/elemA[2]='two'
    //root[1]/elemB[1]='three'
    //root[1]/elemA[3]='four'
    //root[1]/elemC[1]/elemB[1]='five'
    

提交回复
热议问题