2015-06-06 24 views
1

在SVG內聯我需要全部更換的XLink用法簡單的內聯XML的SVG,然後刪除「DEFS」部分,刪除所有:屬性。這個是需要的,因爲SVG查看器是用來支持xlinks的。更換的XLink使用XSLT

初始簡化XML

<?xml version="1.0" encoding="utf-8"?> 
<svg xmlns="http://www.w3.org/2000/svg"> 
    <boo:metadata> 
    <boo:text line-space="1.5" minimum-size="15" regular-size="20"/> 
    </boo:metadata> 
    <g transform="translate(149,60)"> 
     <rect x="0" y="0" fill-opacity="0.6" width="579" height="150"/> 
      <defs><!-- huge section with predefined items--> 
       <g id="ne"> 
        <path id="ne..."/> 
       </g> 
       <g id="nw"> 
        <path id="nw.."/> 
       </g> 
       <g id="rt2"> 
        <rect id="RT2" /> 
        <path id="some cool path id"/> 
       </g> 
       <g id="rt3"> 
        <rect id="rt3sss" rx="2" ry="2"/> 
       </g> 
       <g boo:type="Icon" id="AIRPORT" boo:replacementWords="FLUGHAFEN"> 
        <rect id="ICON_AIRPORT" fill="#FCFFFF" height="15" width="15"/> 
        <path id="ICON_AIRPORTPATH"/> 
       </g> 
      </defs> 

      <g boo:side="R" id="sssss" transform="translate(184,0)"> 
       <g transform="translate(0.000000,0.000000)"> 
        <g boo:style="HorizontalAlignment:Center;VerticalAlignment:Bottom;" transform="translate(63.202000,126.903002)"> 
         <g transform="translate(0.000000,0.000000)"> 
          <!-- actual usage --> 
          <use xlink:actuate="onLoad" xlink:type="simple" xlink:show="embed" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#NE" boo:style="HorizontalAlignment:Left;"/> 
         </g> 
         <g transform="translate(23.045999,0.000000)" boo:style="HorizontalAlignment:Left;Margin:0 5 0 5;"> 
          <g transform="translate(0.000000,0.000000)" boo:style="Margin:0 1 0 1;"> 
          <g transform="scale(1.150000,1.1500000)"> 
           <!-- actual usage --> 
           <use xlink:actuate="onLoad" xlink:type="simple" xlink:show="embed" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#RT2"/> 
          </g> 
          <text transform="translate(16,13)" text-anchor="middle">4</text> 
         </g> 
        </g> 
       </g> 
      </g> 
     </g> 
    </g> 
</svg> 

預期結果

<?xml version="1.0" encoding="utf-8"?> 
<svg xmlns="http://www.w3.org/2000/svg"> 
    <g transform="translate(149,60)"> 
     <rect x="0" y="0" fill-opacity="0.6" width="579" height="150"/> 
      <g id="sssss" transform="translate(184,0)"> 
       <g transform="translate(0.000000,0.000000)"> 
        <g transform="translate(63.202000,126.903002)"> 
         <g transform="translate(0.000000,0.000000)"> 
          <path id="ne..."/> 
         </g> 
         <g transform="translate(23.045999,0.000000)"> 
          <g transform="translate(0.000000,0.000000)"> 
          <g transform="scale(1.150000,1.1500000)">       
           <rect id="RT2" /> 
           <path id="some cool path id"/> 
          </g> 
          <text transform="translate(16,13)" text-anchor="middle">4</text> 
         </g> 
        </g> 
       </g> 
      </g> 
     </g> 
    </g> 
</svg> 
+0

簡化你的示例是一個好主意,但它應該保持名稱空間的格式良好,並且示例使用前綴'boo',但不聲明它的示例不是名稱空間格式良好。 –

回答

1

這解決了我自己。這裏主要的問題是XSL模板中的命名空間使用不正確。

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:boo="..." xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg"> 
    <!-- copy everything as is --> 
    <xsl:template match="@*|node()" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <!-- replace xlink uses to real svg objects --> 
    <xsl:template match="svg:use"> 
     <xsl:copy-of select="/*/*/*/*[@id=substring(current()/@xlink:href, 2)]"/> 
    </xsl:template> 
    <!-- remove unneeded defs section --> 
    <xsl:template match="svg:defs"/> 
    <!-- remove all unneeded cjv nodes and attributes --> 
    <xsl:template match="@boo:*"/> 
    <xsl:template match="boo:*"/> 
    <!-- remove comments and whitespaces --> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="comment()"/> 
    <!-- EXPERIMENTAL - remove id and type attributes --> 
    <xsl:template match="@id"/> 
    <xsl:template match="@type"/> 
</xsl:stylesheet> 
0

更好的路徑將是

<xsl:template match="svg:use"> 
    <xsl:copy-of select="//*[@id=substring(current()/@xlink:href, 2)][1]"/> 
</xsl:template> 

'// *' 相匹配,從根,在任何深度任何後代。終端'[1]'表示如果碰巧有兩個具有指定ID(不應該是)的節點,請選擇第一個節點。

在我自己在這個問題上攻擊我也想給新複製的元素替換使用元素的ID,但是被證明非常棘手,所以我包裹圍着它

<xsl:template match="svg:use"> 
    <g> 
    <!-- copy id, transform, etc through from use reference --> 
    <xsl:apply-templates select="@*"/> 
    <xsl:copy> 
     <xsl:apply-templates select="//*[@id=substring(current()/@xlink:href, 2)][1]"/> 
    </xsl:copy> 
    </g> 
</xsl:template> 

最後,當你複製一個模板時,你複製了它們中所有元素的所有id,並且,如果你像我一樣有一個符號的多個副本,這是一件壞事。所以我翻譯所有的ID,以類:

<!-- generally, change ids to classes --> 
<xsl:template match="@id"> 
    <xsl:attribute name="class"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

很顯然,我使用XSL:複製而不是XSL:複製的使這些修補程序將正常工作。我的代碼存在問題 - 它會在我生成的g元素周圍包含虛假的無屬性使用元素 - 但它呈現OK。