Java SAX解析器:当Child元素也包含相同元素时,读取父元素的元素

时间:2016-05-06 15:35:03

标签: java xml sax saxparser

 <MyWorld> 
 <MyWorldId>SGSNPackage2</MyWorldId> 
 <MyNation> 
 <state>GROWING</state> 
 </MyNation> 
 <state>HAPPY</state> 
 </MyWorld> 

My Parser类:

import java.io.IOException;
import java.io.StringReader;
import java.util.*;

import javax.xml.parsers.*;

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;



public class MyParser extends DefaultHandler {

    private static final String EMPTY_VALUE = "";
    private final StringBuilder characters = new StringBuilder();
    private boolean read;
    private boolean elementFound;
    private boolean elementPropertyFound;
    private boolean elementIdFound;
    private boolean elementWithIdFound;
    private boolean elementProperty;
    private boolean elementPropertyIsList;
    private List<String> properties;
    private final Set<String> propertyAlreadyExist = new HashSet<String>();
    private String elementType;
    private List<String> primaryKeyAttributes;
    private String elementIdValue;
    private String elementIdName;

    private Map<String, Object> elementPropertiesMap;

    Map<String, Object> complexMapAttribute = new HashMap<>();

    public void setAttributes(final List<String> attributes) {
        this.properties = attributes;
    }

    public void setFdnType(final String fdnType) {
        this.elementType = fdnType;
    }

    public void setPrimaryKeyAttributes(final List<String> primaryKeyAttributes) {
        this.primaryKeyAttributes = primaryKeyAttributes;
    }

    public void setKeyValue(final String keyValue) {
        this.elementIdValue = keyValue;
    }

    @Override
    public void startElement(final String uri, final String localName, final String qName, final Attributes attribute) throws SAXException {
        if (qName.equalsIgnoreCase(elementType)) {
            if (!elementWithIdFound) {
                elementFound = true;
            } else {
                elementWithIdFound = false;
            }
        } else if (primaryKeyAttributes.contains(qName) && elementFound) {
            elementIdFound = true;
            read = true;
        } else if (properties.contains(qName) && elementWithIdFound) {
            if (propertyAlreadyExist.contains(qName)) {
                elementPropertyIsList = true;
            }
            propertyAlreadyExist.add(qName);
            elementIdName = qName;
            elementPropertyFound = true;
            read();
            read = true;
            elementProperty = false;
        } else if(elementFound && elementWithIdFound && elementPropertyFound){
            elementProperty = true;
            read();
            read = true;
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public void endElement(final String uri, final String localName, final String qName) throws SAXException {
        final String text;
        if (primaryKeyAttributes.contains(qName) || properties.contains(qName)) {
            if (elementFound && elementWithIdFound && elementPropertyFound) {
                text = readBuffer();
                if (elementIdName != null) {
                    if(elementPropertyIsList) {
                        if(elementProperty){
                            if(null != elementPropertiesMap.get(elementIdName) && elementPropertiesMap.get(elementIdName)!= EMPTY_VALUE){
                                final List<Map<String,Object>> listOfComplexAttribute = new ArrayList<>();
                                if(elementPropertiesMap.get(elementIdName) instanceof List){
                                    listOfComplexAttribute.addAll((List<Map<String, Object>>) elementPropertiesMap.get(elementIdName));
                                }else{
                                    listOfComplexAttribute.add((Map<String, Object>) elementPropertiesMap.get(elementIdName));
                                }
                                listOfComplexAttribute.add(new HashMap<String, Object>(complexMapAttribute));
                                elementPropertiesMap.put(elementIdName, new ArrayList<Map<String, Object>>(listOfComplexAttribute));

                            }else{
                                elementPropertiesMap.put(elementIdName, new HashMap<String, Object>(complexMapAttribute));
                            }
                            complexMapAttribute.clear();
                        }else{
                            final List<Object> attributeValueList = new ArrayList<>();
                            if(null != elementPropertiesMap.get(elementIdName) && elementPropertiesMap.get(elementIdName)!= EMPTY_VALUE){
                                if(elementPropertiesMap.get(elementIdName) instanceof List){
                                    attributeValueList.addAll((List<Object>) elementPropertiesMap.get(elementIdName));
                                }else{
                                    attributeValueList.add(elementPropertiesMap.get(elementIdName));
                                }
                                attributeValueList.add(text);
                                elementPropertiesMap.put(elementIdName, new ArrayList<Object>(attributeValueList));
                            }else{
                                elementPropertiesMap.put(elementIdName,text);      
                            }
                        }

                    } else {
                        if (elementProperty) {
                            elementPropertiesMap.put(elementIdName,new HashMap<String, Object>(complexMapAttribute));
                            complexMapAttribute.clear();
                        } else {
                            elementPropertiesMap.put(elementIdName,text);      
                        }
                    }
                    elementIdName = null;
                    elementPropertyFound =false;
                }
            } else {
                if (elementIdFound) {
                    if (readBuffer().equalsIgnoreCase(elementIdValue)) {
                        elementWithIdFound = true;
                    } else {
                        elementIdFound = false;
                        elementWithIdFound = false;
                        elementFound = false;
                        elementIdName = null;
                    }
                }
            }
        }else if (elementFound && elementWithIdFound && elementPropertyFound && elementProperty){
            text = readBuffer();
            complexMapAttribute.put(qName, text);

        }
    }

    @Override
    public void characters(final char[] ch, final int start, final int length) throws SAXException {
        if (read) {
            characters.append(new String(ch, start, length));
        }
    }


    public void parseData(final String data) {
        elementPropertiesMap = new HashMap<>();
        for (String attributeName : properties) {
            elementPropertiesMap.put(attributeName, EMPTY_VALUE);
        }
        final SAXParserFactory parserFactor = SAXParserFactory.newInstance();
        try {
            final SAXParser parser = parserFactor.newSAXParser();
            parser.parse(new InputSource(new StringReader(data)), this);
        } catch (ParserConfigurationException | SAXException | IOException e) {
            throw new RuntimeException((String) e.getMessage());
        }
    }



    private void read() {
        read = true;
        characters.setLength(0);
    }

    private String readBuffer() {
        final String chars = characters.toString();
        characters.setLength(0);
        read = false;
        return chars;
    }
}

我有上面的XML,我想阅读MyWorld的状态。我的SAX解析器将状态值返回给{GROWING。 HAPPY} astribures / element可以多次出现,所以我会相应处理。

我想要什么,当我在解析它时尝试找到状态时,我应该只获得“HAPPY”?

我如何实现它?

为你们提供帮助,为你们提供了一百万美元!

0 个答案:

没有答案