更新:解析并清理SVG;保持选择属性,删除内部g元素

时间:2013-11-10 22:44:24

标签: xml regex parsing svg batch-processing

我正在尝试重新创建一批(360个文件)SV​​G,因为它们被赋予<clip path>标记,指向<rect>标记内的<defs>标记。它还创建了一个带有fill属性的<polygon>元素。我正在尝试删除<clipPath><defs><polygon>标记,但保留<rect>标记并为其指定多边形的填充属性。

我试图在正则表达式中这样做,但它太复杂了,似乎不能很好地完成。

我试图在java中使用xml解析器类进行操作,但我无法弄清楚如何访问属性(我尝试使用.getAttributes()方法,但它不会拉出属性元素)。

以下是我的一些示例代码:

<defs>
    <rect id="SVGID_1_" y="0" width="1023.88" height="100.08"/>
</defs>
<clipPath id="SVGID_2_">
    <use xlink:href="#SVGID_1_"  display="none" overflow="visible"/>
</clipPath>
<polygon clip-path="url(#SVGID_2_)" fill="#E81E25" points="-0.12,0 -0.12,100.08 1023.88,100.08 1023.88,0"/>

这应该是:

<rect fill="#E81E25" width="1023.88" height="100.08"/>

如何使用<rect>标记将360个文件批量转换为我想要的格式?

2 个答案:

答案 0 :(得分:0)

XSLT非常适合。那是你想要的:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:svg="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns="http://www.w3.org/2000/svg">

  <!-- Identity transform for all cases except the ones we want to delete -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- We do nothing for clipPaths and polygons -->
  <xsl:template match="svg:clipPath|svg:polygon"/>

  <!-- We only copy rects from defs -->
  <xsl:template match="svg:defs">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="svg:rect">
    <xsl:variable name="clipPathId" select="//svg:use[substring(@xlink:href,2) = current()/@id]/../@id"/>
    <rect>
      <xsl:copy-of select="@*"/>
      <xsl:copy-of select="//svg:polygon[@clip-path=concat('url(#', $clipPathId, ')')]/@fill"/>
    </rect>
  </xsl:template>
</xsl:stylesheet>

这假设您要删除所有 <clipPath><polygon>元素以及剥离所有<defs>元素,只保留<rect>元素在里面找到。

使用您喜欢的任何XSLT处理器(Saxon,Xalan,xsltproc,msxsl ......)。

答案 1 :(得分:0)

序言:由于您的文件是由其他程序生成的,因此您可以假设所有标记看起来都相同,所以您可以尝试忽略它,它是'xml':风险很小。如果您的文件来自不同的来源(或该程序的不同版本),我的建议不会起作用或至少更复杂!

我要做的是解析(每个)文件,拆分数据并重新编码,这只是一个提示,我试图不使用语言特定的东西:

- 让我们调用它 - 你可以使用的主要ID是:“id = SVGID_xxx _”

迭代文件和正则表达式:

<rect.*id="([^"]*).*width="([^"]*).*height="([^"]*)
           ^--R1            ^--R2          ^--R3

保持数据(取决于您的语言)

rect_array[R1].width=R2     // or $rect_list[$R1]["w"]=R2; // php like
rect_array[R1].height=R3

然后是第二次迭代

<polygon.*?\(([^)]*).*?fill=.([^'"]*)
           ^--R1 (id again)   ^--color     

并将其添加到您的哈希/数组/地图

rect_array[R1].fill=color     // or $rect_list[$R1]["f"]=color; // php like

最后一步是迭代你的列表/数组并重新确定它

for_all_in(rect_array).do    // foreach($rect_array as $rd) 
puts/echo rect="<rect ...    //   echo "<rect width='rd[w]' ... 

HTH