【问题标题】:How do you traverse and store XML in Blackberry Java app?如何在 Blackberry Java 应用程序中遍历和存储 XML?
【发布时间】:2010-04-10 02:08:47
【问题描述】:

我在访问 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();
    }

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

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

感谢任何帮助。

谢谢

【问题讨论】:

    标签: java xml arrays blackberry associative


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

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

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

      【讨论】:

        【解决方案3】:
         //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 );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          相关资源
          最近更新 更多