Разобрать файл xbrl в python

Я работаю над парсером xml. Цель состоит в том, чтобы проанализировать ряд различных XML-файлов, где префиксы и теги остаются согласованными, но пространства имен меняются.

Поэтому я пытаюсь либо:

  • чтобы разобрать xml просто <prefix:tags> без разрешения (замены) префикса пространством имен. Префиксы остаются неизменными от документа к документу.
  • для автоматической загрузки пространств имен, чтобы идентификатор (<prefix:tag>) можно было заменить соответствующим пространством имен.
  • просто разобрать xml по тегу

Я пробовал с xml.etree.ElementTree.

Я также просмотрел lxml. Я не нашел никаких параметров конфигурации XMLParser в lxml, который мог бы мне помочь, хотя здесь я мог прочитать ответ, в котором автор предполагает, что lxml должен автоматически собирать для меня пространства имен.

Интересно, что parsed_file = etree.XML(file) завершается с ошибкой:

lxml.etree.XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1

Один из примеров файлов, которые я хотел бы разобрать, приведен здесь


person NoIdeaHowToFixThis    schedule 15.05.2014    source источник
comment
items = tree.xpath("*[local-name(.) = 'a_tag_goes_here']") вроде справляется со своей задачей   -  person NoIdeaHowToFixThis    schedule 15.05.2014


Ответы (2)


Не заботьтесь о префиксах ns, заботьтесь о полных пространствах имен

Иногда люди заботятся об этих коротких префиксах и забывают, что они имеют второстепенное значение. Это всего лишь короткая ссылка на полное пространство имен. Например.

xmlns:trw="http://www.trw.com/20131231"

в xml означает, что с этого момента "trw:" означает полное пространство имен "http://www.trw.com/20131231". Обратите внимание, что этот префикс может быть переопределен в любое другое пространство имен в любом последующем элементе и может иметь совершенно другое значение.

С другой стороны, когда вас интересует реальное значение, то есть полное пространство имен, вы можете думать о "trw:row" как о "{http://www.trw.com/20131231}row". Это переведенное значение будет надежным и не изменится при изменении префикса.

Разбор упомянутого xml

Ссылка на http://edgar.sec.gov/Archives/edgar/data/1267097/000104746914000925/trw-20131231.xml приводит к xml, который проверяется xmlstarlet и который lxml может анализировать.

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

lxml и пространства имен

lxml хорошо работает с пространствами имен. Это позволяет вам использовать выражения XPath, которые используют пространства имен. С управлением префиксом пространства имен на выходе немного сложнее, так как он зависит от атрибутов xmlns, которые являются частью сериализованного документа. Если вы хотите изменить префиксы, вы должны каким-то образом организовать эти атрибуты xmlns, часто перемещая все в корневой элемент. В то же время lxml отслеживает полное пространство имен каждого элемента, поэтому в момент сериализации оно будет учитывать это полное имя, а также действительный в настоящее время префикс для этого пространства имен.

Обработка этих атрибутов xmlna требует немного больше кода, см. документацию lxml.

person Jan Vlcinsky    schedule 15.05.2014

items = tree.xpath("*[local-name(.) = 'a_tag_goes_here']")

сделал работу. Кроме того, мне пришлось просмотреть сгенерированный список items вручную, чтобы определить другие нужные мне функции фильтрации.

person NoIdeaHowToFixThis    schedule 16.05.2014