2010-04-10 2 views
2

У меня проблема с доступом к содержимому XML-документа. Моя цель такова: Возьмите XML-источник и проанализируйте его в справедливом эквиваленте ассоциативного массива, а затем сохраните его как устойчивый объект.Как вы перемещаете и храните XML в приложении Blackberry Java?

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", нет "имя"

В идеале, я бы в конечном итоге с чем-то вроде [{1 = машины, 2 = лодки}]

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

Thanks

ответ

1

Вот исправленная версия вашей программы. Изменения, которые я сделал, следующие:

  • Я удалил материал 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

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

Вот изменения, которые я должен был сделать: Несмотря на то, что я строю в 1.5, getTextContent не был доступен. Мне пришлось использовать category = n.getFirstChild(). GetNodeValue(); для получения значения каждого узла. Хотя может быть и простое решение, такое как обновление моих настроек сборки, я недостаточно разбираюсь в требованиях BB, чтобы знать, когда можно безопасно отклониться от рекомендуемых по умолчанию настроек сборки.

В основном, я должен был изменить эту строку:

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

так, что он читал из InputStream поставляется с моего веб-сервера, а не обязательно локальный файл - даже если мне интересно, если хранить xml local будет более эффективным, чем хранение вектора, полного хеш-таблиц. ...

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

Очевидно, что я пропустил соединительную часть HTTP ради сохранения этого читаемого.

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

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); 
Смежные вопросы