我需要帮助:D。我正在使用Web服务返回类似的xml文件到下面的那个:
<books>
<item_1>
<name></name>
<type></type>
</item_1>
<item_2>
<name></name>
<type></type>
</item_2>
<item_3>
<name></name>
<type></type>
</item_3>
...
...</books>
问题是我不知道如何在Android中解析它。如果'books'标签的子元素具有相同的名称(item而不是:item_1,item_2,item_3 ......),那么一切都会好的。然后我可以轻松使用SAX解析器。
你知道我怎么能在Android中削减这种文件吗?
谢谢, 马克斯
编辑:
我的问题是&lt;&lt;&gt; books&gt;的子元素标签啤酒编号(item1,item2,item3等)所以我无法识别它们。如果'books'标签只有'item'子项,这不会有问题 - 所以我可以使用SAX解析器并获取'item'列表
答案 0 :(得分:1)
你所描述的问题听起来并不那么难:如果你可以放心地假设books元素的每个孩子都是“item”,那么你可以调用你的“item”处理程序“为每个孩子。
这是伪代码(我认为)可行,假设&lt; books&gt;始终只是文档的顶级元素:
class BookHandler extends DefaultHandler {
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
if (localName.equals("books") {
// Don't need to do anything with the top level element
return;
}
else {
handleItem(namespaceURI, localName, qName, atts);
}
}
public void endElement(String namespaceURI, String localName, String qName) {
if localName.equals("books") {
// Stop parsing and exit.
}
else {
// Stop parsing one item
}
}
private void handleItem(String namespaceURI, String localName,
String qName, Attributes atts) {
// Handle one item, including handling the "name" and
// "type" child attributes
if (localName.equals("name") {
// handle the name
}
else if (localName.equals("type") {
// handle the type
}
}
}
即使是伪代码,这也过于简单和丑陋。另一种方法,但可能过分夸大您的需求,是将您的应用程序分解为多个ContentHandler
类,在您到达某些元素的开头或结尾时将责任分开。
例如:假设将BookHandler的一个实例传入parser.parse()调用,以处理顶级元素。然后:
class BookHandler extends DefaultHandler {
private ContentHandler m_parentHandler;
private ContentHandler m_childHandler = null;
// ... == appropriate args for the DefaultHandler constructor
public BookHandler(ContentHandler parent, Attributes atts, ...) {
super(...);
m_parentHandler = parent;
parent.getXMLReader().setHandler(this);
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
if (localName.equals("books") {
// Don't need to do anything with the top level element
return;
}
else {
// Assume it's a new item element. (Note: ItemHandler's constructor
// changes the parser's ContentHandler.)
m_childHandler = new ItemHandler(this, atts, ...);
}
}
public void endElement(String namespaceURI, String localName, String qName) {
if localName.equals("books") {
// Stop parsing and exit.
}
else {
// Note that this won't be called for "item" elements, UNLESS the
// ItemHandler's endElement method explicitly invokes this method.
// Stop parsing one item
}
}
}
class ItemHandler extends DefaultHandler {
private ContentHandler m_parentHandler;
// ItemInfo is a class that holds all info about the current item
private ItemInfo m_ItemInfo = null;
// ... == appropriate args for the DefaultHandler constructor
public ItemHandler(ContentHandler parent, Attributes atts, ...) {
super(...);
m_parentHandler = parent;
m_ItemInfo = new ItemInfo(atts);
parent.getXMLReader().setHandler(this);
}
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
if (localName.equals("name") {
// Handle the name. Update the current item as needed.
}
else if (localName.equals("type") {
// Handle the type. Update the current item as needed.
}
}
public void endElement(String namespaceURI, String localName, String qName) {
if localName.equals("name" || localName.equals("type") {
// Do nothing (?)
}
else {
// Stop parsing the current item;
// let the parent class handle the next element.
getXMLReader().setHandler(m_parentHandler);
// OPTIONALLY -- depending on your app's needs -- call the
// parent's endElement() method to let it know that we reached
// the end of an item.
m_parentHandler.endElement(namespaceURI, localName, qName);
}
}
}
该方案提供了更大的灵活性和更多的重用可能性。例如,“books”元素现在可能是某些其他元素的子元素,比如“部门”,对这些类没有太大要求。
伪代码无论如何都不完美。 (首先,我想更多地考虑关闭处理程序的位置 - 在父类或孩子中。另一方面,我可能已经过度保存对父母和孩子的引用。这些课程。)但我希望它能为您提供可以开始使用的想法。
答案 1 :(得分:0)
我之前使用过DocumentBuilderFactory
URL connectURL;
InputStream is;
NodeList names;
NodeList types
try
{
connectURL = new URL("http://example.com/exampleservice");
try
{
URLConnection connection = connectURL.openConnection();
is = connection.getInputStream();
} catch (IOException e)
{
e.printStackTrace();
}
} catch (MalformedURLException e1)
{
e1.printStackTrace();
}
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder docBuillder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuillder.parse(is);
names = doc.getElementsByTagName("name");
types = doc.getElementsByTagName("type");
} catch (ParserConfigurationException e)
{
e.printStackTrace();
} catch (SAXException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
这应该产生NodeLists,它应该包含你想要玩的东西。
谢谢,
ElDog
答案 2 :(得分:0)
这似乎是一种非常奇怪的XML格式,无法为其编写架构。我假设你无法控制它?做一些类似的事情会更有意义。
如果您使用的是dom解析器,则可以在不知道元素名称的情况下遍历元素树。在您的books元素中,只需致电getChildNodes。
使用SAX解析器,在您的处理程序中,您只需要查找包含item的元素名称,而不是完全等于item。类似的东西:
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.contains("item")){
// create some item object
}
}