1

我正在尝试从引用大量命名空间的 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())

返回真。

4

1 回答 1

0

作为参考,我发现这个问题的最佳解决方案是使用来自https://www.ibm.com/support/knowledgecenter/vi/SSEPGG_10.1.0/com.ibm.db2.luw.xml.doc/doc的 xslt 样式表/r0054369.html

strip_namespaces <- function(x){
    stylesh <- '<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)
}
于 2019-05-16T07:44:50.990 回答