使用R在SVG文件中选择样式属性

时间:2014-07-04 15:20:52

标签: xml r svg

我想使用R读取SVG文件,根据数据值更改SVG文件,然后将SVG导出为光栅图像,如png。

通过一些研究,我已经确定SVGMapping包会让我在那里使用,但是这个包已经从CRAN存储库中删除了,因此我对将它用于我可能依赖的任何东西都很谨慎。

因为SVG是XML,我的计划是使用XML包来改变我的SVG文件的属性。然后我想使用shell函数调用inkscape将SVG转换为PNG。

我在浏览XML结构时遇到了问题。正如您在下面的SVG中看到的,我创建了三个不同颜色的矩形。我想用R来改变颜色。

我可以在SVG中阅读并使用以下内容导航到属性:

doc <- xmlTreeParse("c:\\Temp\\drawing.svg", getDTD = F)
doc$children$svg$children$g$children[1]$rect$attributes

然后我可以使用以下方式提取所有样式信息:

doc$children$svg$children$g$children[1]$rect$attributes["style"]

但是,结果只是一个包含填充,描边,不透明等值的字符串。

"fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" 

有没有办法选择一个样式属性,比如填充,所以我可以添加一个新的颜色代码?

我猜我最终可能会使用基于正则表达式的东西,但我想要问一下是否有另一种方法(即更简单!)来浏览样式属性。

SVG文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="744.09448819"
   height="1052.3622047"
   id="svg2"
   version="1.1"
   inkscape:version="0.48.2 r9819"
   sodipodi:docname="New document 1">
  <defs
     id="defs4" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.53183594"
     inkscape:cx="375"
     inkscape:cy="520"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="739"
     inkscape:window-height="558"
     inkscape:window-x="175"
     inkscape:window-y="175"
     inkscape:window-maximized="0" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <rect
       style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
       id="rect2985"
       width="180.50679"
       height="165.46455"
       x="30.084465"
       y="225.03938"
       rx="0"
       ry="0" />
    <rect
       style="fill:#00ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
       id="rect2985-1"
       width="180.50679"
       height="165.46455"
       x="312.12634"
       y="230.68022"
       rx="0"
       ry="0" />
    <rect
       style="fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
       id="rect2985-7"
       width="180.50679"
       height="165.46455"
       x="118.45758"
       y="456.31369"
       rx="0"
       ry="0" />
  </g>
</svg>

1 个答案:

答案 0 :(得分:0)

目前,您需要处理XML包外部的style。在这种情况下,您可以拆分 ";"":"

xData <- xmlParse("c:\\Temp\\drawing.svg")
out <- lapply(xData["//svg:rect"], xmlGetAttr, name = "style")
out <- sapply(out, strsplit, ";")
out <- lapply(out, strsplit, ":")
out <- lapply(out, function(x){
  sapply(x, function(y){`names<-`(y[2], y[1])})
}
)
out <- `names<-`(do.call(rbind.data.frame, out), names(out[[1]]))

out$fill <- "#000000"
out <- apply(out, 1, function(x) paste(names(out), x, sep = ':'))
out <- apply(out, 2, function(x) paste(x, collapse = ";"))

# remove old styles
lapply(xData["//svg:rect"], removeAttributes, .attrs = 'style')
# add new styles

mapply(addAttributes, node = xData["//svg:rect"], style = out)

> xData["//svg:rect"]
[[1]]
<rect id="rect2985" width="180.50679" height="165.46455" x="30.084465" y="225.03938" rx="0" ry="0" style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/> 

[[2]]
<rect id="rect2985-1" width="180.50679" height="165.46455" x="312.12634" y="230.68022" rx="0" ry="0" style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/> 

[[3]]
<rect id="rect2985-7" width="180.50679" height="165.46455" x="118.45758" y="456.31369" rx="0" ry="0" style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/> 

attr(,"class")
[1] "XMLNodeSet"