xml - 使用命名空间在 R 中创建 XML

标签 xml r namespaces

我正在尝试在 R 中构建一个如下所示的 XML 结构。注意默认命名空间、其他命名空间和位于备用命名空间中的内部 Name 对象:

<?xml version = "1.0" encoding="UTF-8"?>
<sld xmlns="http://www.o.net/sld" 
     xmlns:ogc="http://www.o.net/ogc" 
     xmlns:se="http://www.o.net/se"
     version="1.1.0" >
<layer>
<se:Name>My Layer</se:Name>
</layer>
</sld>

这段代码很接近,标签上的命名空间没问题,但根标签中没有默认命名空间:

require(XML)
makesimple = function(){
    z = xmlTree("sld",
                namespaces=list(
                    "ogc"="http://www.o.net/ogc",
                    "se"="http://www.o.net/se"),
                attrs=list(version="1.1.0")
                )
    z$addNode("layer", close=FALSE)
    z$setNamespace("se")
    z$addNode("Name","My Layer")
    z$closeTag()
    z
}
> cat(saveXML(makesimple()))

给予

<?xml version="1.0"?>
 <sld 
  xmlns:ogc="http://www.o.net/ogc"
  xmlns:se="http://www.o.net/se" 
  version="1.1.0">
  <layer>
    <se:Name>My Layer</se:Name>
  </layer>
</sld>

但是如果我添加一个默认的(未命名的)命名空间,那么为内部元素设置命名空间什么都不做。将上面的一行更改为:

z = xmlTree("sld",
            namespaces=list("http://www.o.net/sld",
                "ogc"="http://www.o.net/ogc",
                "se"="http://www.o.net/se"),
            attrs=list(version="1.1.0")
            )

这给了我:

<?xml version="1.0"?>
  <sld 
    xmlns="http://www.o.net/sld" 
    xmlns:ogc="http://www.o.net/ogc"
    xmlns:se="http://www.o.net/se"
   version="1.1.0">
  <layer>
    <Name>My Layer</Name>
  </layer>
</sld>

它在根元素中具有正确的所有命名空间,但我想要用于内部元素的命名空间已经消失。

请注意,我开始使用 newXMLDocnewXMLNode 函数来处理这个问题,直到我阅读文档说:

 While the
 functions are available, their direct use is not encouraged.
 Instead, use ‘xmlTree’ as the functions need to be used within a
 strict regime to avoid corrupting C level structures.

我正准备放弃使用 package::XML 构建这些东西,而只是使用模板系统构建它们(可能是 package::brew) .

最佳答案

这里有一个轻微的变体,它也保留了默认的命名空间。 FWIW 我认为 XML::newXMLNode() (在我的代码中)和 z$addNode (在另一个答案中)与 DTL 书中的文档和示例背道而驰( ?)。您应该能够在此处指定“se”命名空间,并通过祖先中的命名空间定义解析它。但事实似乎并非如此。

library(XML)

makesimple <- function() {
  z <- newXMLNode("sld", newXMLNode("layer"), attrs = list(version="1.1.0"),
                  namespaceDefinitions = c("http://www.o.net/sld",
                                           ogc = "http://www.o.net/ogc",
                                           se = "http://www.o.net/se"))
  z_doc <- newXMLDoc(node = z)
  Name <- newXMLNode("Name", "My Layer", parent = z[["layer"]])
  setXMLNamespace(Name, "se")
  z_doc
}
cat(saveXML(makesimple()))
#> <?xml version="1.0"?>
#> <sld xmlns="http://www.o.net/sld" xmlns:ogc="http://www.o.net/ogc" xmlns:se="http://www.o.net/se" version="1.1.0">
#>   <layer>
#>     <se:Name>My Layer</se:Name>
#>   </layer>
#> </sld>

强制 namespace 解析的另一种方法似乎是在创建节点时指定 namespace 前缀,但不指定父节点。然后,当节点作为子节点添加时, namespace 确实从祖先正确解析。

library(XML)

makesimple2 <- function() {
  z <- newXMLNode("sld", newXMLNode("layer"), attrs=list(version="1.1.0"),
                  namespaceDefinitions = c("http://www.o.net/sld",
                                           ogc = "http://www.o.net/ogc",
                                           se = "http://www.o.net/se"))
  z_doc <- newXMLDoc(node = z)
  Name <- newXMLNode("se:Name", "My Layer")
  addChildren(z[["layer"]], Name)
  z_doc
}
cat(saveXML(makesimple2()))
#> <?xml version="1.0"?>
#> <sld xmlns="http://www.o.net/sld" xmlns:ogc="http://www.o.net/ogc" xmlns:se="http://www.o.net/se" version="1.1.0">
#>   <layer>
#>     <se:Name>My Layer</se:Name>
#>   </layer>
#> </sld>

关于xml - 使用命名空间在 R 中创建 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32939229/

相关文章:

xml - 使用 Linq to XML 检查 XML 子元素是否存在

r - 使用 dplyr::across 执行 dplyr::select

r - 无法使用表的聚合来计算平均值,结果显示为 N/A

vb.net - 新 pc 导致 "namespace of type specified in the imports doesn' t 包含任何公共(public)成员”在 VB.NET

c++ - 将 boost::intrusive_ptr 与嵌套类一起使用

android - 应用程序图标不显示在操作栏中 (Android Studio 1.0.1)

android - 如何在 Android 中并排显示两个图像?

java - java中推荐的XML解析器(绝对是xml的初学者)

r - 安装 Rstem 包的问题

c# - 有条件地编译整个命名空间 - C#