我有一个XML文档,我需要以提取,针对每个项目,价值解析:
<title>
<description>
<articleDate>
<story>
<author>
<photo>
<caption>
我与DOM很努力,但我失去的,因为每个节点
<item>
根
<channel>
有3个孩子:
<article>
<media>
<link>
我已经使用SAX有很多成功的,它的快速和简单。我得到了这个简单的和“递归”的方法,从一些网站,展示了基于模板解析器生成下图显示的想法。我只是做手工,但是从“的DefaultHandler”类扩展。
这里真正的窍门是,每个对象类型得到它自己的“DefaultHandler的”扩展,它知道如何解析类型和单靠类型。这使得重构和重用你的解析器的XML解析器和可能。然后,当你看到某种类型的新的子“元素”的开始,你创建一个空的子容器和它的“的DefaultHandler”的延伸。将当前处理到一个该类型,让它递归终日啃食掉。
有改进,我可以这样做太像推一些常见的方法达到扩展“的DefaultHandler”我自己的基类。我还创建了“IXMLSerializer”接口,这样我可以很快写这些了。有可能是太有更好的方式。
在此基础上,我想出了一个策略,通过对每个元素类型的创建对象开始...
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);
}
}
}
也许这可以帮助: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();
}
}
}
项目是您root.You必须在here使用SAX解析器oarse这个xml.Look