2016-09-15 66 views
1

我想用matplotlib生成一些svg圖像並將它們嵌入到html和pdf報告中。我在WebKit中遇到this bug,這是我的應用程序使用的,以及Adobe Acrobat中的另一個渲染錯誤。這兩個問題都是由matplotlib<clipPath>元素放置在svg文件的末尾造成的。使用XSLT重新排列/合併SVG文件的節點

若要兩種錯誤我想在文件的開始使用XSLT所有<defs>節點合併成一個節點周圍

例SVG

<svg height="288pt" version="1.1" viewBox="0 0 576 288" width="576pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
    <defs> 
     <style type="text/css"> 
      *{stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:100000;} 
     </style> 
    </defs> 
    <g id="figure_1"> 
     ... 

    </g> 
    <defs> 
     <clipPath id="p8596dc1504"> 
      <rect height="230.5245" width="211.84" x="339.7475" y="28.90175"/> 
     </clipPath> 
     <clipPath id="p9534ff1f4d"> 
      <rect height="230.5245" width="211.84" x="66.534375" y="28.90175"/> 
     </clipPath> 
    </defs> 
</svg> 

所需的輸出

<svg height="288pt" version="1.1" viewBox="0 0 576 288" width="576pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
    <defs> 
     <style type="text/css"> 
      *{stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:100000;} 
     </style> 
     <clipPath id="p8596dc1504"> 
      <rect height="230.5245" width="211.84" x="339.7475" y="28.90175"/> 
     </clipPath> 
     <clipPath id="p9534ff1f4d"> 
      <rect height="230.5245" width="211.84" x="66.534375" y="28.90175"/> 
     </clipPath> 
    </defs> 
    <g id="figure_1"> 
     ... 

    </g> 
</svg> 

這是我目前的XSLT。該代碼正確地刪除了<defs>部分,但我在文檔開始處獲得的所有內容都是<defs xmlns=""/>,沒有孩子。

XSL文件

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes" doctype-system="about:legacy-compat"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*"> 
     <xsl:copy> 
      <defs> 
       <xsl:copy-of select="/svg/defs/*"/> 
      </defs> 
      <xsl:apply-templates select="*[name()!='defs']"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

輸出繼電器

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
    <defs xmlns=""/> 
    <g id="figure_1"> 
     ... 

    </g> 
</svg> 

我仍然試圖環繞XSLT我的頭。我究竟做錯了什麼?

回答

3

您的樣式表沒有考慮源XML使用的命名空間

嘗試:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:svg="http://www.w3.org/2000/svg" 
xmlns="http://www.w3.org/2000/svg"> 
<xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes" doctype-system="about:legacy-compat"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <defs> 
       <xsl:copy-of select="/svg:svg/svg:defs/*"/> 
      </defs> 
      <xsl:apply-templates select="*[not(self::svg:defs)]"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

完美,這我想要做什麼!在[SO回答](http://stackoverflow.com/a/18515711/3419537)中的評論我基於我提到的命名空間上的代碼,但我不知道如何將它們考慮在內 – user3419537

+0

@Pfafait好點。這不是原來的代碼,而是傾向於關注主要問題並忽略其他問題。現在添加。 –