Asked
11 years, 5 months ago
Viewed
446 times
Currently I´m using this method to find a specified tag in a XML document:
public static String parseDocument(byte[] stream, String tagName, String resourceName) {
String result = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(stream));
document.getDocumentElement().normalize();
Node tag = document.getElementsByTagName(tagName).item(0);
result = tag.getAttributes().getNamedItem(resourceName).getNodeValue();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
But this returns only the first match. How can I implement a method that returns all found tags?
asked Dec 2, 2011 at 14:30
NodeList tags = document.getElementsByTagName(tagName);
List<String> values = new ArrayList<String>();
for (int i = 0 ; i < tags.getLength() ; i++) {
values.add(tags.item(i).getNodeValue());
}
answered Dec 2, 2011 at 14:35
pappap
26.9k6 gold badges41 silver badges46 bronze badges
Hi I want to get a list of all tags in an XML, and if some tags carry particular attribute I also want the value of the attribute.
For example here are one specific examples,
<?xml version="1.0" encoding="utf-8"?>
<bbc.mobile.news.view.AVGalleryView android:background="@drawable/gallery_item_selector" android:padding="2.0dip" android:focusable="true" android:layout_width="139.0dip" android:layout_height="130.0dip"
xmlns:android="http://schemas.android.com/apk/res/android">
<bbc.mobile.news.view.NewsImageView android:id="@id/galleryItemView" android:background="#00000000" android:padding="0.0dip" android:layout_width="@dimen/thumbnail_width" android:layout_height="@dimen/thumbnail_height" />
<TextView android:textSize="13.0sp" android:textColor="@color/thumbnail_text" android:ellipsize="end" android:id="@id/articleTitleId" android:background="@color/thumbnail_text_bg" android:paddingLeft="5.0dip" android:paddingTop="2.0dip" android:paddingBottom="5.0dip" android:layout_width="139.0dip" android:layout_height="50.0dip" android:maxLines="2" android:layout_below="@id/galleryItemView" />
<ImageView android:layout_gravity="center_vertical" android:id="@id/avIconView" android:background="#99000000" android:duplicateParentState="true" android:layout_width="40.0dip" android:layout_height="40.0dip" android:src="@drawable/icon_playvideo_selected" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" />
</bbc.mobile.news.view.AVGalleryView>
I am not interested about parent child relationship, I want to iterate to the deepest child if a parent-child relationship exists. and I also want the android:id and android:name attribute value if exists in a particular element.
problem is that you cannot know how deep a parent-child relation can be and where in the xml it will be. And you also dont know the tag names before. I can think of using recursion in my code , but I believe there is a simpler solution
asked Oct 11, 2012 at 3:00
P basakP basak
4,83411 gold badges39 silver badges62 bronze badges
3
I found the solution, it was very simple, did not know before that getElementsByTagName("*")
does that, here is my code,
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element " + doc.getDocumentElement().getNodeName());
NodeList nodeList=doc.getElementsByTagName("*");
for (int i=0; i<nodeList.getLength(); i++)
{
// Get element
Element element = (Element)nodeList.item(i);
System.out.println(element.getNodeName());
}
I have found the solution here
answered Oct 11, 2012 at 3:21
P basakP basak
4,83411 gold badges39 silver badges62 bronze badges
2
P basak’s answer is perfect. I have used below code with the referenced url by P basak.
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class XMLToTags {
public static void main(String[] args) {
try {
BufferedReader bf = new BufferedReader(
new InputStreamReader(System.in));
System.out.print("Enter XML File name: ");
String xmlFile = bf.readLine();
File file = new File(xmlFile);
if(file.exists()){
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(xmlFile);
NodeList list = doc.getElementsByTagName("*");
System.out.println("XML Elements: ");
for (int i=0; i<list.getLength(); i++) {
Element element = (Element)list.item(i);
System.out.println(element.getNodeName());
}
}
else{
System.out.print("File not found!");
}
}
catch (Exception e) {
System.exit(1);
}
}
}
answered Feb 4, 2017 at 11:47
NickNick
9771 gold badge9 silver badges16 bronze badges
Данные есть буквально везде, во всех видах документов. Но не все это полезно, поэтому необходимо проанализировать его, чтобы получить нужные части. XML-документы являются одними из таких документов, которые содержат данные. Они очень похожи на файлы HTML, поскольку имеют почти такую же структуру. Следовательно, вам нужно будет проанализировать их, чтобы получить жизненно важную информацию, как и при работе с HTML.
Есть два основных аспекта синтаксического анализа файлов XML. Они есть:
- Поиск тегов
- Извлечение из тегов
Вам нужно будет найти тег, содержащий нужную информацию, а затем извлечь эту информацию. Вы узнаете, как делать и то, и другое при работе с файлами XML до конца этой статьи.
Монтаж
BeautifulSoup — одна из наиболее часто используемых библиотек, когда дело доходит до парсинга веб-страниц с помощью Python. Поскольку файлы XML похожи на файлы HTML, он также может их анализировать. Однако для анализа XML-файлов с помощью BeautifulSoup лучше всего использовать Python lxml парсер.
Вы можете установить обе библиотеки, используя пип инструмент установки, используя команду ниже:
pip install bs4 lxml
Чтобы убедиться, что обе библиотеки успешно установлены, вы можете активировать интерактивную оболочку и попробовать импортировать обе. Если ошибка не появляется, то можно приступить к остальной части статьи.
Вот пример:
$ питон
Python 3.7.4 (теги / v3.7.4: e09359112e, 8 июл 2019, 20:34:20)
[MSC v.1916 64 бит (AMD64)] на win32
Введите «помощь», «авторские права», «кредиты» или «лицензия» для получения дополнительной информации.
>>> импорт bs4
>>> импортировать lxml
>>>
Прежде чем двигаться дальше, вы должны создать XML-файл из фрагмента кода ниже. Это довольно просто и должно соответствовать сценариям использования, о которых вы узнаете в оставшейся части статьи. Просто скопируйте, вставьте в свой редактор и сохраните; такое имя как образец.xml должно хватить.
Дерево
Первый
Второй
В третьих
Один
Два
Двойняшки
Четвертый
Теперь в вашем скрипте Python; вам нужно будет прочитать XML-файл как обычный файл, а затем передать его в BeautifulSoup. В оставшейся части этой статьи будет использоваться bs_content переменная, поэтому важно, чтобы вы сделали этот шаг.
# Импортировать BeautifulSoup
из bs4 импортировать BeautifulSoup как bs
content = []
# Прочитать XML-файл
с открытым («образец.xml «,» r «) как файл:
# Прочитать каждую строку в файле, readlines () вернет список строк
content = file.readlines ()
# Объединить строки в списке в строку
content = «».присоединиться (содержание)
bs_content = bs (контент, «lxml»)
Пример кода выше импортирует BeautifulSoup, затем он читает XML-файл как обычный файл. После этого он передает контент в импортированный BeautifulSoup библиотека, а также выбранный парсер.
Вы заметите, что код не импортирует lxml. Это не обязательно, как BeautifulSoup выберут lxml парсер в результате передачи «Lxml» в объект.
Теперь вы можете перейти к остальной части статьи.
Поиск тегов
Один из важнейших этапов синтаксического анализа XML-файлов — поиск тегов. Есть несколько способов сделать это при использовании BeautifulSoup; поэтому вам нужно знать о некоторых из них, чтобы иметь лучшие инструменты для соответствующей ситуации.
Вы можете найти теги в XML-документах:
- Имена
- Отношения
Поиск тегов по именам
Есть два метода BeautifulSoup, которые вы можете использовать при поиске тегов по именам. Однако варианты использования различаются; давай посмотрим на них.
найти
Исходя из личного опыта, вы будете использовать найти метод чаще, чем другие методы поиска тегов в этой статье. Тег find получает имя тега, который вы хотите получить, и возвращает объект BeautifulSoup тега, если он его находит; иначе он возвращается Никто.
Вот пример:
>>> результат = bs_content.найти («данные»)
>>> print (результат)
Один
>>> результат = bs_content.find («уникальный»)
>>> print (результат)
Двойняшки
>>> результат = bs_content.найти («отец»)
>>> print (результат)
Никто
>>> результат = bs_content.найти («мать»)
>>> print (результат)
Никто
Если вы посмотрите на пример, вы увидите, что найти метод возвращает тег, если он соответствует имени, иначе он возвращает None. Однако, если вы внимательно посмотрите на него, вы увидите, что он возвращает только один тег.
Например, когда найти («данные») был вызван, он вернул только первый тег данных, но не вернул другие.
ПОПАЛСЯ: В найти метод вернет только первый тег, который соответствует его запросу.
Итак, как вам найти и другие теги? Это приводит нас к следующему методу.
найти все
В найти все метод очень похож на найти метод. Единственное отличие состоит в том, что он возвращает список тегов, соответствующих его запросу. Когда он не находит ни одного тега, он просто возвращает пустой список. Следовательно, найти все всегда будет возвращать список.
Вот пример:
>>> результат = bs_content.find_all («данные»)
>>> print (результат)
[Один, Два]
>>> результат = bs_content.find_all («ребенок»)
>>> print (результат)
[
Первый
,
Второй
,
В третьих
Один
Два
Двойняшки
,
Четвертый
]
>>> результат = bs_content.find_all («отец»)
>>> print (результат
[]
>>> результат = bs_content.find_all («мать»)
>>> print (результат)
[]
Теперь, когда вы знаете, как использовать найти а также найти все методы, вы можете искать теги в любом месте XML-документа. Однако вы можете сделать свои поисковые запросы более эффективными.
Вот как:
Некоторые теги могут иметь одинаковое имя, но разные атрибуты. Например, ребенок теги имеют название атрибут и разные значения. Вы можете выполнять конкретные поисковые запросы на основе этих.
Посмотри на это:
>>> результат = bs_content.find («ребенок», «имя»: «Роза»)
>>> print (результат)
Второй
>>> результат = bs_content.find_all («ребенок», «имя»: «Роза»)
>>> print (результат)
[
Второй
]
>>> результат = bs_content.find («ребенок», «имя»: «Джек»)
>>> print (результат)
Первый
>>> результат = bs_content.find_all («ребенок», «имя»: «Джек»)
>>> print (результат)
[
Первый
]
Вы увидите, что в использовании найти а также найти все методы здесь: у них обоих есть второй параметр.
Когда вы передаете словарь в качестве второго параметра, найти а также найти все методы продолжают свой поиск, чтобы получить теги, атрибуты и значения которых соответствуют предоставленной паре ключ: значение.
Например, несмотря на использование найти метод в первом примере, он вернул второй ребенок тег (вместо первого ребенок tag), потому что это первый тег, который соответствует запросу. В найти все tag следует тому же принципу, за исключением того, что он возвращает все теги, соответствующие запросу, а не только первый.
Поиск тегов по отношениям
Хотя поиск по тегам менее популярен, чем поиск по именам, вы также можете искать теги по отношениям. На самом деле это скорее навигация, чем поиск.
В XML-документах есть три ключевых отношения:
- Родитель: Тег, в котором существует ссылочный тег.
- Дети: Теги, которые существуют в ссылочном теге.
- Братья и сестры: Теги, которые существуют на том же уровне, что и ссылочный тег.
Из объяснения выше вы можете сделать вывод, что ссылочный тег является наиболее важным фактором при поиске тегов по отношениям. Поэтому давайте поищем ссылочный тег и продолжим статью.
Взгляните на это:
>>> third_child = bs_content.find («ребенок», «имя»: «Голубой плющ»)
>>> print (третий_ ребенок)
В третьих
Один
Два
Двойняшки
В приведенном выше примере кода ссылочный тег для остальной части этого раздела будет третьим ребенок тег, хранящийся в третий_ребенок Переменная. В подразделах ниже вы увидите, как искать теги на основе их родительских, одноуровневых и дочерних отношений с тегом ссылки.
В поисках родителей
Чтобы найти родительский тег ссылочного тега, вы воспользуетесь родитель атрибут. Это возвращает родительский тег, а также теги под ним. Такое поведение вполне понятно, поскольку дочерние теги являются частью родительского тега.
Вот пример:
>>> результат = третий_ ребенок.родитель
>>> print (результат)
Первый
Второй
В третьих
Один
Два
Двойняшки
Четвертый
В поисках детей
Чтобы найти дочерние теги ссылочного тега, вы воспользуетесь дети атрибут. При этом будут возвращены дочерние теги, а также вложенные теги под каждым из них. Это поведение также понятно, так как дочерние теги часто также имеют свои собственные дочерние теги.
Следует отметить, что дети атрибут возвращает дочерние теги в качестве генератора. Поэтому, если вам нужен список дочерних тегов, вам придется преобразовать генератор в список.
Вот пример:
>>> результат = список (третий_деток.дети)
>>> print (результат)
[‘ n Третий n’,
Один
Два
Двойняшки
, ‘ n’]
Если вы внимательно посмотрите на приведенный выше пример, вы заметите, что некоторые значения в списке не являются тегами. Это то, чего вам нужно остерегаться.
ПОПАЛСЯ: В дети Атрибут не только возвращает дочерние теги, но также возвращает текст в ссылочном теге.
Поиск братьев и сестер
Последний в этом разделе — поиск тегов, которые являются родственниками тега ссылки. Для каждого ссылочного тега могут быть одноуровневые теги до и после него. В previous_siblings Атрибут вернет одноуровневые теги перед ссылочным тегом, а next_siblings Атрибут вернет родственные теги после него.
Так же, как дети атрибут, previous_siblings а также next_siblings атрибуты вернут генераторы. Поэтому вам нужно преобразовать в список, если вам нужен список братьев и сестер.
Взгляните на это:
>>> previous_siblings = список (третий_деток.previous_siblings)
>>> печать (предыдущие_сиблинги)
[‘ n’,
Второй
, ‘ n’,
Первый
, ‘ n’]
>>> next_siblings = список (третий_ ребенок.next_siblings)
>>> print (next_siblings)
[‘ n’,
Четвертый
]
>>> печать (предыдущие_сиблинги + следующие_сиблинги)
[‘ n’,
Второй
, ‘ n’,
Первый
,
‘ n’, ‘ n’,
Четвертый
, ‘ n’]
Первый пример показывает предыдущих братьев и сестер, второй — следующих братьев и сестер; затем оба результата объединяются для создания списка всех братьев и сестер для ссылочного тега.
Извлечение из тегов
При синтаксическом анализе XML-документов большая часть работы заключается в поиске правильных тегов. Однако, когда вы их найдете, вы также можете извлечь определенную информацию из этих тегов, и именно этому вас научит этот раздел.
Вы увидите, как извлечь следующее:
- Значения атрибутов тега
- Текст тега
- Содержимое тега
Извлечение значений атрибутов тегов
Иногда у вас может быть причина извлечь значения атрибутов в теге. Например, в следующей паре атрибут-значение: name = «Роза», вы можете извлечь «Роза.”
Для этого вы можете использовать получать метод или доступ к имени атрибута с помощью [] как индекс, как и при работе со словарем.
Вот пример:
>>> результат = третий_ ребенок.получить («имя»)
>>> print (результат)
Синий плющ
>>> result = third_child [«имя»]
>>> print (результат)
Синий плющ
Извлечение текста тега
Если вы хотите получить доступ к текстовым значениям тега, вы можете использовать текст или же струны атрибут. Оба вернут текст в теге и даже дочерние теги. Тем не менее текст Атрибут вернет их как одну объединенную строку; в то время как струны атрибут вернет их как генератор, который вы можете преобразовать в список.
Вот пример:
>>> результат = третий_ ребенок.текст
>>> print (результат)
‘ n Третий n nОдин nДва nДва n n’
>>> результат = список (третий_деток.струны)
>>> print (результат)
[‘ n Третий n’, ‘ n’, ‘Один’, ‘ n’, ‘Два’, ‘ n’, ‘Близнецы’, ‘ n’, ‘ n’]
Извлечение содержимого тега
Помимо извлечения значений атрибутов и текста тегов, вы также можете извлечь все содержимое тегов. Для этого вы можете использовать содержание атрибут; это немного похоже на дети атрибут и даст те же результаты. Однако пока дети атрибут возвращает генератор, содержание атрибут возвращает список.
Вот пример:
>>> результат = третий_ ребенок.содержание
>>> print (результат)
[‘ n Третий n’,
Один
Два
Двойняшки
, ‘ n’]
Красивая печать
До сих пор вы видели некоторые важные методы и атрибуты, которые полезны при синтаксическом анализе XML-документов с помощью BeautifulSoup. Но если вы заметили, когда вы печатаете теги на экране, они имеют какой-то кластерный вид. Хотя внешний вид может не иметь прямого влияния на вашу продуктивность, он может помочь вам более эффективно анализировать и сделать работу менее утомительной.
Вот пример обычной печати:
>>> print (третий_ ребенок)
В третьих
Один
Два
Двойняшки
Однако вы можете улучшить его внешний вид, используя украсить метод. Просто позвоните в украсить метод на теге во время печати, и вы получите что-то визуально приятное.
Взгляните на это:
Заключение
Анализ документов — важный аспект поиска данных. XML-документы довольно популярны, и, надеюсь, вы лучше подготовитесь к их работе и извлечете нужные данные.
Из этой статьи вы теперь можете:
- искать теги по именам или отношениям
- извлекать данные из тегов
Если вы чувствуете себя совершенно потерянным и плохо знакомы с библиотекой BeautifulSoup, вы можете ознакомиться с руководством по BeautifulSoup для начинающих.
Мне другое интересно, существует ли метод или функция, которая проходит по каждому тегу, просто обычный цикл пройдёт только по тегам «верхнего уровня», он не будет обходить их детей.
Написано
более года назад
KeR 0 / 0 / 0 Регистрация: 05.12.2009 Сообщений: 103 |
||||||||
1 |
||||||||
24.11.2012, 01:40. Показов 6116. Ответов 9 Метки нет (Все метки)
предположим есть файл
каким образом списать данные из такого текстового документа чтобы они например отображались в месадж боксе след образом:
0 |
Doomer3D 179 / 179 / 32 Регистрация: 23.11.2012 Сообщений: 344 Записей в блоге: 1 |
||||||||||||||||
24.11.2012, 10:42 |
2 |
|||||||||||||||
Регулярные выражения — проще всего.
Создаем примерно так:
Если сразу все, то так:
Добавлено через 9 минут
0 |
3077 / 2221 / 639 Регистрация: 02.08.2011 Сообщений: 6,099 |
|
24.11.2012, 11:49 |
3 |
Используй Xml-parser. XmlDocument class.
0 |
0 / 0 / 0 Регистрация: 05.12.2009 Сообщений: 103 |
|
24.11.2012, 12:13 [ТС] |
4 |
огромное спасибо, но я не могу почему ничего не выводиться. И еще один вопрос, а каким образом вывести информацию только из под одного тэга? (например инф между <Name></Name>)? Добавлено через 2 минуты
Используй Xml-parser. XmlDocument class. спасибо за предложение, но по заданию это мне нужно сделать именно из текстовика, иксэмели там будут далее, но с ними я еще хоть как то разобрался, а вот с этими регулярными выражениями ужэ много факов различных прочитал, особых продвижений нет.
0 |
3077 / 2221 / 639 Регистрация: 02.08.2011 Сообщений: 6,099 |
|
24.11.2012, 12:28 |
5 |
насколько я знаю, xml-парсер работает с xml-документами, но это не значит, что эти документы находятся в файлах с расширением .xml, можно загрузить из текстовика.
1 |
KeR 0 / 0 / 0 Регистрация: 05.12.2009 Сообщений: 103 |
||||||||
24.11.2012, 13:34 [ТС] |
6 |
|||||||
Файл предположим вот такой
Добавлено через 1 минуту Добавлено через 49 минут
0 |
Doomer3D 179 / 179 / 32 Регистрация: 23.11.2012 Сообщений: 344 Записей в блоге: 1 |
||||
24.11.2012, 13:36 |
7 |
|||
Получить информацию из тега:
0 |
IamRain 3077 / 2221 / 639 Регистрация: 02.08.2011 Сообщений: 6,099 |
||||
24.11.2012, 13:48 |
8 |
|||
вот мой код:
только выводит все данные почему-то в одной строке, но выводит)
1 |
0 / 0 / 0 Регистрация: 05.12.2009 Сообщений: 103 |
|
24.11.2012, 14:14 [ТС] |
9 |
Да, спасибо за помощь именно так и реализовал)
0 |
Spectral-Owl 606 / 581 / 157 Регистрация: 29.06.2010 Сообщений: 1,620 |
||||
26.11.2012, 14:13 |
10 |
|||
для любого xml файла:
0 |