1

我需要将所有xlink用法替换为 SVG 中的简单内联 xml,然后删除“ defs ”部分并删除所有boo : 属性。这个是必需的,因为打算使用的 SVG 查看器不支持 xlinks。

初始简化 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>
4

2 回答 2

2

自己解决了这个问题。这里的主要问题是 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>
于 2015-06-06T19:01:05.867 回答
0

更好的路径是

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

'//*' 从根匹配任何深度的任何后代。终端“[1]”表示如果碰巧有两个具有指定 id 的节点(不应该有),请选择第一个。

在我自己对这个问题的攻击中,我还想为新复制的元素提供被替换的 use 元素的 id,但事实证明这很棘手,所以我在它周围加上了一个g :

<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:copy而不是xsl:copy-of以便这些修复工作。我的代码有问题 - 它在我生成的g元素周围包装了一个虚假的无属性使用元素 - 但它呈现正常。

于 2015-07-28T15:53:14.577 回答