R -从XML文件中删除一些节点

1u4esq0p  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(164)

我被这个问题困住了:我正在使用R。我想删除父节点“uid”、“seanceRef”和“sessionRef”。
我用remove_node()试过了,但看起来确实有效。我该怎么做呢?

<?xml version='1.0' encoding='UTF-8'?>
<compteRendu xmlns="http://schemas.assemblee-nationale.fr/referentiel">
  <uid>CRSANR5L16S2022E1N003</uid>
  <seanceRef>RUANR5L16S2022IDS26199</seanceRef>
  <sessionRef>SCR5A2022E1</sessionRef>
  <metadonnees> 
    I want to keep metadonnees
  </metadonnees>
  </compteRendu>
xbp102n0

xbp102n01#

您没有在xpath中包含xml命名空间前缀。
如果我们查看您的原始文档:

library(xml2)

doc <- read_xml('test.xml')

doc
#> {xml_document}
#> <compteRendu xmlns="http://schemas.assemblee-nationale.fr/referentiel">
#> [1] <uid>CRSANR5L16S2022E1N003</uid>
#> [2] <seanceRef>RUANR5L16S2022IDS26199</seanceRef>
#> [3] <sessionRef>SCR5A2022E1</sessionRef>
#> [4] <metadonnees>\n    I want to keep metadonnees\n  </metadonnees>

然后我们看到第二行定义了xml命名空间,所有属于这个命名空间的节点都必须通过它们的命名空间前缀来引用,否则它们将找不到:

xml_find_all(doc, '//uid')
#> {xml_nodeset (0)}

默认的前缀是d1,但是我们可以通过以下操作来检查它是什么:

xml_ns(doc)
#> d1 <-> http://schemas.assemblee-nationale.fr/referentiel

因此,我们可以通过执行以下操作获得所需的节点:

remove_me <- xml_find_all(doc, '//d1:uid')

remove_me
#> {xml_nodeset (1)}
#> [1] <uid>CRSANR5L16S2022E1N003</uid>

要删除此节点,可以执行以下操作:

xml_remove(remove_me)

doc
#> {xml_document}
#> <compteRendu xmlns="http://schemas.assemblee-nationale.fr/referentiel">
#> [1] <seanceRef>RUANR5L16S2022IDS26199</seanceRef>
#> [2] <sessionRef>SCR5A2022E1</sessionRef>
#> [3] <metadonnees>\n    I want to keep metadonnees\n  </metadonnees>

根据您的用例,您可能会发现从XML中完全剥离名称空间以使XPath更易于使用更容易:

doc <- read_xml('test.xml')
xml_ns_strip(doc)
xml_find_all(doc, '//uid')
#> {xml_nodeset (1)}
#> [1] <uid>CRSANR5L16S2022E1N003</uid>
bf1o4zei

bf1o4zei2#

对于OP或未来的读者,还可以考虑XSLT,这是一种专用语言,设计用于转换XML文件,特别是当删除节点的逻辑变得复杂和有条件时。可以使用xslt包(xml2)的姊妹包)运行XSLT 1.0脚本。XSLT是一种行业语言,因此可以移植到其他语言(Java、Python、PHP)和executables
具体来说,运行Identity Transform模板来复制XML,然后在要删除的节点上写入一个空模板。当然,使用临时前缀来重新Map默认名称空间以引用要删除的节点。

    • XSLT***(另存为. xsl文件,一种特殊的. xml文件)*
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           xmlns:ref="http://schemas.assemblee-nationale.fr/referentiel">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- IDENTITY TRANSFORM -->
    <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
    </xsl:template>
    
    <!-- EMPTY TEMPLATE TO REMOVE ALL SUCH NODES -->
    <xsl:template match="ref:uuid|ref:seanceRef"/>
    
</xsl:stylesheet>
    • R**
library(xml2)
library(xslt)

# READ XML AND XSLT
doc <- read_xml("Input.xml", package = "xslt")
style <- read_xml("Script.xsl", package = "xslt")

# RUN TRANSFORMATION
doc <- xml_xslt(doc, style)
           
# SAVE EDITED DOC TO FILE           
output <- write_xml(doc, "Output.xml")

相关问题