Откройте файл XML из res/xml в Android

Я создал приложение Java, которое открывает файл xml, который выглядит примерно так:

<AnimalTree>
  <animal>
    <mammal>canine</mammal>
    <color>blue</color>
  </animal>
  <!-- ... -->
</AnimalTree>

И я могу открыть его, используя:

File fXmlFile = getResources.getXml("res/xml/data.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList animalNodes = doc.getElementsByTagName("animal");

Затем я могу просто создать узел, поместить объект в ListArray, а затем делать с объектами все, что захочу, пока я перебираю ListArray.

for (int temp = 0; temp < animalNodes.getLength(); temp++) {
Node nNode = animalNodes.item(temp);     
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
question thisAnimal = new animal();
thisAnimal.mammal = getTagValue("mammal",eElement);
// ...

Легко и просто! Только теперь в Android я не могу просто прочитать файл «res/xml/data.xml», потому что для «File();» требуется String, а не integer (id). Вот где я потерялся. Можно ли как-то заставить "File();" открыть файл, или это невозможно без использования SAXparser или XPP? (и то и другое я действительно не могу понять, как бы я ни старался.)
Если я вынужден использовать эти методы, может ли кто-нибудь показать мне какой-нибудь простой код, аналогичный моему примеру?


person jeremy    schedule 01.12.2010    source источник


Ответы (3)


Если он находится в дереве ресурсов, ему будет назначен идентификатор, поэтому вы можете открыть для него поток с помощью функции openRawResource:

InputStream is = context.getResources().openRawResource(R.xml.data);

Что касается работы с XML в Android, эта ссылка на ibm.com невероятно тщательно.

См. Listing 9. DOM-based implementation of feed parser по этой ссылке.

Получив входной поток (см. выше), вы можете передать его экземпляру DocumentBuilder:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("TheTagYouWant");

Имейте в виду, я не делал этого лично — я предполагаю, что код, предоставленный IBM, работает.

person jcollum    schedule 01.12.2010
comment
Я не понимаю? Могу ли я тогда изменить это на строку и поместить ее в File(); ? Ресурс IBM, который вы оставили, показывает, как просто вытащить xml из Интернета. Я не понимаю, почему это так сложно? Можете ли вы создать версию псевдокода того, что я написал выше? Спасибо. - person jeremy; 02.12.2010
comment
Это лучше, и я видел это на сайте IBM, но getInputStream(); находится в классе BaseFeedParser, который реализует класс FeedParser, не указанный на сайте IBM. Я создал класс BaseFeedParser в своем коде, но eclipse выдает мне ошибку о FeedParser. - person jeremy; 03.12.2010
comment
этот сайт говорит: Однако DOM обычно потребляет больше памяти, поскольку все сначала считывается в память. Это может быть проблемой на мобильных устройствах под управлением Android, но может быть удовлетворительным в некоторых случаях использования, когда размер XML-документа никогда не будет очень большим. Можно предположить, что разработчики Android догадались, что синтаксический анализ SAX будет гораздо более распространен в приложениях Android, поэтому для него были предусмотрены дополнительные утилиты. Это очень плохо. мой XML будет иметь около 100 объектов. Метод DOM добавил в мой проект 50 строк кода, это слишком непрактично. - person jeremy; 03.12.2010
comment
Используете ли вы XML для локального хранения данных? Я бы рекомендовал SQLite в этом случае. Он встроен в стек. - person jcollum; 03.12.2010
comment
Re: FeedParser: это интерфейс: public interface FeedParser - person jcollum; 03.12.2010
comment
Кроме того, там есть код, который использует поток ввода через SAX, ищите это: SAXParserFactory factory = SAXParserFactory.newInstance(); - person jcollum; 03.12.2010
comment
Также обратите внимание, что openRawResource(R.xml.data) в настоящее время выдает ошибку lint в Android Studio: ожидаемый ресурс типа raw. Вместо этого используйте getXml() (см. ответ BfD). - person LarsH; 13.06.2017

Я попробовал подход с использованием openRawResource и получил исключение SAXParseException. Поэтому вместо этого я использовал getXml для получения XmlPullParser. Затем я использовал next() для просмотра событий синтаксического анализа. Фактический файл — res/xml/dinosaurs.xml.

XmlResourceParser parser = context.getResources().getXml(R.xml.dinosaurs);
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
    switch (eventType) {
        case XmlPullParser.START_DOCUMENT :
            Log.v(log_tag, "Start document");
            break;
        case XmlPullParser.START_TAG :
            Log.v(log_tag, "Start tag " + parser.getName() );
            break;
        case XmlPullParser.END_TAG :
            Log.v(log_tag, "End tag " + parser.getName() );
            break;
        case XmlPullParser.TEXT :
            Log.v(log_tag, "Text " + parser.getText() );
            break;
        default :
            Log.e(log_tag, "Unexpected eventType = " + eventType );
    }
    eventType = parser.next();
}
person BfD    schedule 03.03.2017

Попробуй это,

this.getResources().getString(R.xml.test); // returns you the path , in string,invoked on activity object
person Abhiram mishra    schedule 27.02.2014