如何在xsl:template中匹配节点和子节点(同名)

时间:2016-06-03 22:26:52

标签: xslt svg layer inkscape

我有一个inkscape svg文件。

简化版:

<svg>
    <g inkscape:label="layerA">
        <g inkscape:label="layerB"/>
    </g>
    <g inkscape:label="layerC">
        <g inkscape:label="layerD"/>
    </g>
</svg>

我想提取图层A(和B)和D。

这适用于直接位于根元素下的A层。

<?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:inkscape="http://www.inkscape.org/namespaces/inkscape"
>

<!-- Auto intend -->
<xsl:output indent="yes"/>

<!-- Copy every other node, element, attribute -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- Do not copy any other group -->
<xsl:template match="svg:g"/>

<!-- Copy all matching groups -->
<xsl:template match="svg:g[@inkscape:label='layerA']|svg:g[@inkscape:label='layerD']">
    <xsl:copy-of select="."/>
</xsl:template>

但它不会复制D层。

所以我的问题是:如何不仅直接匹配根目录下的节点,而且匹配另一个“g”元素下的节点。

3 个答案:

答案 0 :(得分:2)

而不是:

<!-- Do not copy any other group -->
<xsl:template match="svg:g"/>

做的:

<xsl:template match="svg:g">
    <xsl:apply-templates select="svg:g"/>
</xsl:template>

否则你的下一个模板:

<!-- Copy all matching groups -->
<xsl:template match="svg:g[@inkscape:label='layerA']|svg:g[@inkscape:label='layerD']">
    <xsl:copy-of select="."/>
</xsl:template>

永远不会应用于D层。

答案 1 :(得分:0)

完全转型

<div class='bootstrap-select-dropdown-wrapper' ng-if='listofthings.length > 0'>...</div>

应用于提供的XML (添加了名称空间声明以使其格式正确)文档:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:svg="http://www.w3.org/2000/svg"
  xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/*">
    <xsl:copy>
     <xsl:copy-of select=".//svg:g[@inkscape:label='layerA' or @inkscape:label='layerD']"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

产生(我猜的是)想要的正确结果

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
    <g inkscape:label="layerA">
        <g inkscape:label="layerB"/></g>
    <g inkscape:label="layerC">
        <g inkscape:label="layerD"/></g>
</svg>

答案 2 :(得分:0)

再次感谢您的回答!

我只想添加另一种方法来实现我的目标(在svg中使用子层的png导出)。

https://github.com/wader/inkmake

inkfile 如下所示:

output.png input.svg -* +layerA +layerB +layerD

这样可以省去在将许多新的svg文件导出到png之前创建它们的麻烦。

但再次感谢。