安卓:如何分析这种XML的

问题描述 投票:0回答:3

我有一个XML文档,我需要以提取,针对每个项目,价值解析:

<title>
<description>
<articleDate>
<story>
<author>
<photo>
<caption>

我与DOM很努力,但我失去的,因为每个节点

<item>

<channel> 

有3个孩子:

<article>
<media> 
<link>
android xml-parsing
3个回答
1
投票

我已经使用SAX有很多成功的,它的快速和简单。我得到了这个简单的和“递归”的方法,从一些网站,展示了基于模板解析器生成下图显示的想法。我只是做手工,但是从“的DefaultHandler”类扩展。

这里真正的窍门是,每个对象类型得到它自己的“DefaultHandler的”扩展,它知道如何解析类型和单靠类型。这使得重构和重用你的解析器的XML解析器和可能。然后,当你看到某种类型的新的子“元素”的开始,你创建一个空的子容器和它的“的DefaultHandler”的延伸。将当前处理到一个该类型,让它递归终日啃食掉。

有改进,我可以这样做太像推一些常见的方法达到扩展“的DefaultHandler”我自己的基类。我还创建了“IXMLSerializer”接口,这样我可以很快写这些了。有可能是太有更好的方式。

Taking the sting out of SAX

在此基础上,我想出了一个策略,通过对每个元素类型的创建对象开始...

public class CollectionType implements IXMLSerializer{

public static final String  TYPE_TAG = "Collection";

protected IdentityType identity;
protected List<PropertyType> property;
protected List<ItemReferenceType> itemReference;
protected List<SporeType> spore;
protected List<RegionType> region;
protected List<BackpackItemType> backpackItem;


/**
 * Gets the value of the identity property.
 * 
 * @return
 *     possible object is
 *     {@link IdentityType }
 *     
 */
public IdentityType getIdentity() {
    return identity;
}

/**
 * Sets the value of the identity property.
 * 
 * @param value
 *     allowed object is
 *     {@link IdentityType }
 *     
 */
public void setIdentity(IdentityType value) {
    this.identity = value;
}


/**
 * Gets the value of the property property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the property property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getProperty().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link PropertyType }
 * 
 * 
 */
public List<PropertyType> getProperty() {
    if (property == null) {
        property = new ArrayList<PropertyType>();
    }
    return this.property;
}

/**
 * Gets the value of the itemReference property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the itemReference property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getItemReference().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link ItemReferenceType }
 * 
 * 
 */
public List<ItemReferenceType> getItemReference() {
    if (itemReference == null) {
        itemReference = new ArrayList<ItemReferenceType>();
    }
    return this.itemReference;
}

/**
 * Gets the value of the spore property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the spore property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getSpore().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link SporeType }
 * 
 * 
 */
public List<SporeType> getSpore() {
    if (spore == null) {
        spore = new ArrayList<SporeType>();
    }
    return this.spore;
}

/**
 * Gets the value of the region property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the region property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getRegion().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link RegionType }
 * 
 * 
 */
public List<RegionType> getRegion() {
    if (region == null) {
        region = new ArrayList<RegionType>();
    }
    return this.region;
}

/**
 * Gets the value of the backpackItem property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the backpackItem property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getBackpackItem().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link BackpackItemType }
 * 
 * 
 */
public List<BackpackItemType> getBackpackItem() {
    if (backpackItem == null) {
        backpackItem = new ArrayList<BackpackItemType>();
    }
    return this.backpackItem;
}

@Override
public void serializeType(XmlSerializer serializer, String namespace)
        throws IllegalArgumentException, IllegalStateException, IOException {

    serializer.startTag(namespace, TYPE_TAG);
    getIdentity().serializeType(serializer, namespace);

    Iterator<PropertyType> pItor = getProperty().iterator();
    while (pItor.hasNext()){
        pItor.next().serializeType(serializer, namespace);
    }

    Iterator<ItemReferenceType> iItor = getItemReference().iterator();
    while (iItor.hasNext()){
        iItor.next().serializeType(serializer, namespace);
    }

    Iterator<SporeType> sItor = getSpore().iterator();
    while (sItor.hasNext()){
        sItor.next().serializeType(serializer, namespace);
    }

    Iterator<RegionType> rItor = getRegion().iterator();
    while (rItor.hasNext()){
        rItor.next().serializeType(serializer, namespace);
    }

    Iterator<BackpackItemType> bItor = getBackpackItem().iterator();
    while (bItor.hasNext()){
        bItor.next().serializeType(serializer, namespace);
    }

    serializer.endTag(namespace, TYPE_TAG);
}

}

然后,我创建了一个顶级的文件处理器....

public class DocumentHandler extends DefaultHandler {
public static final String      TAG = DocumentHandler.class.getSimpleName();
private static final boolean    mDebugLogging = true;

SAXParserFactory        mSaxParserFactory;
SAXParser               mSaxParser;
XMLReader               mXmlReader;
Stack<String>           mElementStack = new Stack<String>();

private CollectionType  mCollection = null;
private RequestType     mRequest = null;
private ResponseType    mResponse = null;




public DocumentHandler() throws SAXException, ParserConfigurationException{
    mSaxParserFactory = SAXParserFactory.newInstance();
    mSaxParserFactory.setNamespaceAware(true);      //  Must be set true, otherwise no attributes!
    //m_saxParserFactory.setFeature("http://xml.org/sax/features/namespaces", true);
    //m_saxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
    mSaxParser = mSaxParserFactory.newSAXParser();

    if (mDebugLogging) {
        Log.d(TAG, "SAX parser namespace aware? " + mSaxParser.isNamespaceAware());
        Log.d(TAG, "SAX parser is validating? " + mSaxParser.isValidating());
    }
    mXmlReader = mSaxParser.getXMLReader();
}

@Override
public void endDocument() throws SAXException {
    if (mDebugLogging) {
        Log.d(TAG, "Beginning Document Parse");
    }
    super.endDocument();
}




@Override
public void startDocument() throws SAXException {
    if (mDebugLogging) {
        Log.d(TAG, "Ending Document Parse");
    }
    super.startDocument();
}


@Override
public void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes) throws SAXException {
    if (qName.equals("Collection")) {
        mCollection = new CollectionType();
        final DefaultHandler handler = new CollectionHandler(mElementStack, mCollection, attributes, mXmlReader, this);
        mElementStack.push ("ServerResponse");
        mXmlReader.setContentHandler (handler);
    }
    else if (qName.equals("Request")){
        mRequest = new RequestType();
        final DefaultHandler handler = new RequestHandler(mElementStack, mRequest, attributes, mXmlReader, this);
        mElementStack.push("Request");
        mXmlReader.setContentHandler(handler);
    }
    else if (qName.equals("Response")){
        mResponse = new ResponseType();
        final DefaultHandler handler = new ResponseHandler(mElementStack, mResponse, attributes, mXmlReader, this);
        mElementStack.push("Response");
        mXmlReader.setContentHandler(handler);
    }
}


@Override
public void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName) throws SAXException {}


public void parse(InputSource is) throws SAXException, IOException {
    mXmlReader.setContentHandler(this);
    mXmlReader.parse(is);
}


public RequestType parseRequest(InputStream inStream) throws SAXException, IOException {
    final InputSource inSource = new InputSource(inStream);
    parse(inSource);
    return mRequest;
}

public CollectionType parseCollection(InputStream inStream) throws SAXException, IOException {
    final InputSource inSource = new InputSource(inStream);
    parse(inSource);
    return mCollection;
}

public ResponseType parseResponse(InputStream inStream) throws SAXException, IOException {
    final InputSource inSource = new InputSource(inStream);
    parse(inSource);
    return mResponse;
}

}

然后我“而延伸的DefaultHandler”为每种类型的像这样的:

公共类CollectionHandler延伸的DefaultHandler {私人最终的CharArrayWriter m_textBuffer =新的CharArrayWriter();私人最终堆栈m_elementStack;私人最终的DefaultHandler m_parent;私人最终的XMLReader m_parser;

private final CollectionType            m_collection;

public CollectionHandler(Stack<String> path, CollectionType collection, Attributes attributes, XMLReader parser, DefaultHandler parent) throws SAXException{
    m_elementStack = path;
    m_collection = collection;
    m_parser = parser;
    m_parent = parent;
    start(attributes);
}

private void start(Attributes attributes){}


@Override
public void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes) throws SAXException {
    m_textBuffer.reset();

    if (qName.equals("Identity")){
        final IdentityType identity = new IdentityType();
        m_collection.setIdentity(identity);
        final DefaultHandler handler = new IdentityHandler(m_elementStack, identity, attributes, m_parser, this);
        m_elementStack.push("Identity");
        m_parser.setContentHandler(handler);
    }

    if (qName.equals("BackpackItem")){
        final BackpackItemType backpackItem = new BackpackItemType();
        m_collection.getBackpackItem().add(backpackItem);
        final DefaultHandler handler = new BackpackItemHandler(m_elementStack, backpackItem, attributes, m_parser, this);
        m_elementStack.push("BackpackItem");
        m_parser.setContentHandler(handler);
    }

    else if (qName.equals("ItemReference")){
        final ItemReferenceType itemReference = new ItemReferenceType();
        m_collection.getItemReference().add(itemReference);
        final DefaultHandler handler = new ItemReferenceHandler(m_elementStack, itemReference, attributes, m_parser, this);
        m_elementStack.push("ItemReference");
        m_parser.setContentHandler(handler);
    }

    else if (qName.equals("Property")){
        final PropertyType property = new PropertyType();
        m_collection.getProperty().add(property);
        final DefaultHandler handler = new PropertyHandler(m_elementStack, property, attributes, m_parser, this);
        m_elementStack.push("Property");
        m_parser.setContentHandler(handler);
    }

    else if (qName.equals("Region")){
        final RegionType toInsert = new RegionType();
        m_collection.getRegion().add(toInsert);
        final DefaultHandler handler = new RegionHandler(m_elementStack, toInsert, attributes, m_parser, this);
        m_elementStack.push("Region");
        m_parser.setContentHandler(handler);
    }

    else if (qName.equals("Spore")){
        final SporeType toInsert = new SporeType();
        m_collection.getSpore().add(toInsert);
        final DefaultHandler handler = new SporeHandler(m_elementStack, toInsert, attributes, m_parser, this);
        m_elementStack.push ("Spore");
        m_parser.setContentHandler (handler);
    }
}


@Override
public void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName) throws SAXException {
    if (qName.equals("Collection")){
        m_elementStack.pop();
        m_parser.setContentHandler(m_parent);
    }
}

}


2
投票

也许这可以帮助:http://www.mkyong.com/java/how-to-modify-xml-file-in-java-dom-parser/

How to append tags in XML in Android?

另一个例子:

final String xmlFile = "YourFile.xml";
    ArrayList<String> userData = new ArrayList<String>();
    FileInputStream fis;
    InputStreamReader isr;
    String data = null;
    try {
        fis = c.openFileInput(xmlFile);
        isr = new InputStreamReader(fis);
        char[] inputBuffer = new char[fis.available()];
        isr.read(inputBuffer);
        data = new String(inputBuffer);
        isr.close();
        fis.close();
    } catch (FileNotFoundException e3) {
        // TODO Auto-generated catch block
        e3.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    XmlPullParserFactory factory = null;
    try {
        factory = XmlPullParserFactory.newInstance();
    } catch (XmlPullParserException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    factory.setNamespaceAware(true);
    XmlPullParser xpp = null;
    try {
        xpp = factory.newPullParser();
    } catch (XmlPullParserException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    try {
        xpp.setInput(new StringReader(data));
    } catch (XmlPullParserException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    int eventType = 0;
    try {
        eventType = xpp.getEventType();
    } catch (XmlPullParserException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    while (eventType != XmlPullParser.END_DOCUMENT) {
        if (eventType == XmlPullParser.START_DOCUMENT) {
            System.out.println("Start document");
        } else if (eventType == XmlPullParser.START_TAG) {
            System.out.println("Start tag " + xpp.getName());

        } else if (eventType == XmlPullParser.END_TAG) {
            System.out.println("End tag " + xpp.getName());
        } else if (eventType == XmlPullParser.TEXT) {
            userData.add(xpp.getText());
            System.out.println(xpp.getText());
        }
        try {
            eventType = xpp.next();
        } catch (XmlPullParserException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}   

1
投票

项目是您root.You必须在here使用SAX解析器oarse这个xml.Look

© www.soinside.com 2019 - 2024. All rights reserved.