Как вы просматриваете и храните XML в Java-приложении Blackberry? - PullRequest
2 голосов
/ 10 апреля 2010

У меня проблема с доступом к содержимому 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 ниже.Я просто вызываю save (xml) после http ответа выше.Да, 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", нет "name"

В идеале, я хотел бы получить что-то вроде [{1 = cars, 2 = boats}] *

Любая помощь приветствуется.

Спасибо

Ответы [ 3 ]

1 голос
/ 10 апреля 2010

Вот исправленная версия вашей программы. Внесенные мною изменения:

  • Я удалил материал DocBuilder из метода save(). Эти вызовы необходимы для создания нового Document. Если у вас есть такой объект (и вы делаете это, поскольку он передается в качестве аргумента), вам больше не нужен DocumentBuilder. Правильное использование DocumentBuilder показано в методе main ниже.
  • _node, _element не должен быть полями. Они получают новые значения при каждом прохождении цикла внутри save, поэтому я сделал их локальными переменными. Кроме того, я изменил их имена на category и name, чтобы отразить их связь с элементами в документе XML.
  • Нет необходимости создавать новый объект String с помощью new String(). Достаточно простого "" (см. Инициализацию переменных category и name).
  • Вместо цикла по всему (через "*") теперь цикл повторяется по element элементам. Затем существует внутренний цикл, который перебирает дочерние элементы каждого элемента, а именно: его элементы category_id и name.
  • В каждом проходе внутреннего элемента мы устанавливаем либо переменную 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);
  }
0 голосов
/ 08 ноября 2010
 //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 );
0 голосов
/ 10 апреля 2010

Большое спасибо. Только с небольшими изменениями я смог сделать именно то, что искал.

Вот модификации, которые мне пришлось сделать: Хотя я собираю в 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-соединения, чтобы сохранить читаемость.

Ваша помощь спасла меня от целых выходных слепой отладки. Большое спасибо! Надеюсь, этот пост поможет кому-то еще.

...