2

我在访问 XML 文档的内容时遇到问题。我的目标是:获取一个 XML 源并将其解析为与关联数组相当的等价物,然后将其存储为可持久对象。

xml 非常简单:

<root>
<element>
    <category_id>1</category_id>
    <name>Cars</name>
</element>
<element>
    <category_id>2</category_id>
    <name>Boats</name>
</element>
</root>

下面的基本java类。我几乎只是在上面的 http 响应之后调用 save(xml) 。是的,xml 格式正确。

    import java.io.IOException;
    import java.util.Hashtable;

    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;

    import java.util.Vector;
    import net.rim.device.api.system.PersistentObject;
    import net.rim.device.api.system.PersistentStore;
    import net.rim.device.api.xml.parsers.DocumentBuilder;
    import net.rim.device.api.xml.parsers.DocumentBuilderFactory;

public class database{
        private static PersistentObject storeVenue;
        static final long key = 0x2ba5f8081f7ef332L;
        public Hashtable hashtable;
        public Vector venue_list;
        String _node,_element;

    public database()
    {
        storeVenue = PersistentStore.getPersistentObject(key);
    }

    public void save(Document xml)
    {
            venue_list = new Vector();
        storeVenue.setContents(venue_list);


        Hashtable categories = new Hashtable();


        try{

            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory. newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            docBuilder.isValidating();

            xml.getDocumentElement ().normalize ();

            NodeList list=xml.getElementsByTagName("*");
            _node=new String();
            _element = new String();

            for (int i=0;i<list.getLength();i++){

                Node value=list.item(i).getChildNodes().item(0);
                _node=list.item(i).getNodeName();
                _element=value.getNodeValue();

                categories.put(_element, _node);
            }

        }
        catch (Exception e){
            System.out.println(e.toString());
        }

        venue_list.addElement(categories);


        storeVenue.commit();
    }

上面的代码是正在进行的工作,很可能存在严重缺陷。但是,我已经在这几天了。我似乎永远无法获得所有子节点或名称/值对。当我将向量打印为字符串时,我通常会得到如下结果: [{ = root, = element}] 就是这样。没有“category_id”,没有“名称”

理想情况下,我最终会得到类似 [{1 = 汽车,2 = 船}]

任何帮助表示赞赏。

谢谢

4

3 回答 3

1

这是您的程序的固定版本。我所做的更改如下:

  • 我从save()方法中删除了 DocBuilder-stuff。需要这些调用来构造一个新的Document. 一旦你有了这样的对象(因为它是作为参数传入的),你就不再需要DocumentBuilder了。DocumentBuilder下面的方法说明了正确使用的main方法。
  • _node,_element 不必是字段。每次通过内部循环时,它们都会获得新值,save因此我将它们设为局部变量。此外,我将它们的名称更改为categoryname反映它们与 XML 文档中元素的关联。
  • 永远不需要使用new String(). 一个简单""的就足够了(参见categoryname变量的初始化)。
  • "*"现在循环遍历element元素,而不是遍历所有内容(通过)。然后有一个内部循环遍历每个元素的子元素,即:其category_idname元素。
  • 在内部的每次传递中,我们根据手头节点的名称设置category或变量。name
  • 设置为这些变量的实际值是通过node.getTextContent()返回节点封闭标签之间的内容来获得的。

database

  public class database {
     private static PersistentObject storeVenue;
     static final long key = 0x2ba5f8081f7ef332L;
     public Hashtable hashtable;
     public Vector venue_list;

     public database() {
        storeVenue = PersistentStore.getPersistentObject(key);
     }

     public void save(Document xml) {
        venue_list = new Vector();
        storeVenue.setContents(venue_list);

        Hashtable categories = new Hashtable();

        try {

           xml.getDocumentElement().normalize();

           NodeList list = xml.getElementsByTagName("element");

           for (int i = 0; i < list.getLength(); i++) {

              String category = "";
              String name = "";
              NodeList children = list.item(i).getChildNodes();
              for(int j = 0; j < children.getLength(); ++j)
              {
                 Node n = children.item(j);
                 if("category_id".equals(n.getNodeName()))
                    category = n.getTextContent();
                 else if("name".equals(n.getNodeName()))
                    name = n.getTextContent();
              }

              categories.put(category, name);

              System.out.println("category=" + category + "; name=" + name);
           }

        } catch (Exception e) {
           System.out.println(e.toString());
        }

        venue_list.addElement(categories);

        storeVenue.commit();
     }
  }

这是一个主要方法:

  public static void main(String[] args) throws Exception {
     DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
        .newInstance();
     DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
     docBuilder.isValidating();

     Document xml = docBuilder.parse(new File("input.xml"));

     database db = new database();
     db.save(xml);
  }
于 2010-04-10T07:54:04.570 回答
0

非常感谢。只需稍作修改,我就可以完全按照我的要求进行操作。

以下是我必须做的修改: 即使我在 1.5 中构建,getTextContent 也不可用。我不得不使用 category = n.getFirstChild().getNodeValue(); 获取每个节点的值。虽然可能有一个简单的解决方案,比如更新我的构建设置,但我对 BB 要求还不够熟悉,无法知道何时可以安全地偏离默认推荐的构建设置。

总的来说,我不得不改变这一行:

 Document xml = docBuilder.parse(new File("input.xml"));

所以它是从我的网络服务器传递的 InputStream 中读取的,而不一定是本地文件——尽管我想知道存储 xml 本地是否比存储一个充满哈希表的向量更有效。...

InputStream responseData = connection.openInputStream();
 Document xmlParsed = docBuilder.parse(result);

显然,为了保持可读性,我跳过了 HTTP 连接部分。

您的帮助为我节省了整个周末的盲目调试。非常感谢你!希望这篇文章也能帮助其他人。

于 2010-04-10T16:15:42.713 回答
0
 //res/xml/input.xml
 private static String _xmlFileName = "/xml/input.xml";

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 DocumentBuilder builder = factory.newDocumentBuilder();
 InputStream inputStream = getClass().getResourceAsStream( _xmlFileName );
 Document document = builder.parse( inputStream );
于 2010-11-08T12:03:12.863 回答