разбирать xml без пространств имен - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь извлечь информацию из файлов xml (или, точнее: xbrl), которые ссылаются на множество пространств имен. Меня не волнует пространство имен, и я предпочел бы иметь возможность поиска по файлам без указания их.

Вот пример:

require(magrittr)
xml <-xml2::read_xml("http://regnskaber.virk.dk/21560853/ZG9rdW1lbnRsYWdlcjovLzAzLzdlLzk4L2JiLzg4L2NiNzctNDE2ZC1hOWJmLTkxN2QxZWRkMGY0Yg.xml")

этот файл содержит следующий узел:

<cmn:IdentificationNumberOfAuditor contextRef=\"duration_IdentificationOfAuditorDimension_cmn_auditorIdentifier_only_1\">mne18078</cmn:IdentificationNumberOfAuditor>

Я знаю, что могу найти его, используя xml2 :: xml_find_all (xml, '// cmn: IdentificationNumberOfAuditor')

Но это только в том случае, если я знаю префикс пространства имен, и я не уверен, что они даются одинаково во всех тысячах файлов, которые мне нужно обработать. Я надеялся, что это сработает:

xml2::xml_find_all(xml2::xml_ns_strip(xml), '//IdentificationNumberOfAuditor')

потому что я думал, что xml_ns_strip лишит xml-файл информации о пространстве имен. Однако, xml_ns_strip, похоже, вообще ничего не делает, так как:

identical(xml %>% as.character(), xml_ns_strip(xml) %>% as.character())

возвращает истину.

1 Ответ

0 голосов
/ 16 мая 2019

Для справки, лучшее решение, которое я нашел для этой проблемы, это использование таблицы стилей xslt из https://www.ibm.com/support/knowledgecenter/vi/SSEPGG_10.1.0/com.ibm.db2.luw.xml.doc/doc/r0054369.html

strip_namespaces <- function(x){
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

        <!-- keep comments -->
        <xsl:template match="comment()">
          <xsl:copy>
            <xsl:apply-templates/>
          </xsl:copy>
        </xsl:template>

      <xsl:template match="*">
        <!-- remove element prefix -->
        <xsl:element name="{local-name()}">
          <!-- process attributes -->
          <xsl:for-each select="@*">
            <!-- remove attribute prefix -->
            <xsl:attribute name="{local-name()}">
              <xsl:value-of select="."/>
            </xsl:attribute>
          </xsl:for-each>
          <xsl:apply-templates/>
        </xsl:element>
      </xsl:template>
    </xsl:stylesheet>
                      ')
  xslt::xml_xslt(x, stylesh)
}
...