如何在 xsl:template 中匹配节点和子节点(同名)
how to match nodes AND child nodes (same name) in xsl:template
我有一个 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" 元素下的节点。
而不是:
<!-- 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 层。
完成改造:
<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>
应用于提供的 XML(添加命名空间声明以使其格式正确)文档时:
<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>
产生(我猜是)想要的正确结果:
<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="layerD"/>
</svg>
再次感谢您的回答!
我只想添加一种替代方法来实现我的目标(在 svg 中导出包含图层子集的 png)。
https://github.com/wader/inkmake
inkfile 看起来像这样:
output.png input.svg -* +layerA +layerB +layerD
这让我省去了在将它们导出为 png 之前生成许多新 svg 文件的麻烦。
但是再次感谢。
我有一个 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" 元素下的节点。
而不是:
<!-- 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 层。
完成改造:
<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>
应用于提供的 XML(添加命名空间声明以使其格式正确)文档时:
<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>
产生(我猜是)想要的正确结果:
<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="layerD"/>
</svg>
再次感谢您的回答!
我只想添加一种替代方法来实现我的目标(在 svg 中导出包含图层子集的 png)。
https://github.com/wader/inkmake
inkfile 看起来像这样:
output.png input.svg -* +layerA +layerB +layerD
这让我省去了在将它们导出为 png 之前生成许多新 svg 文件的麻烦。
但是再次感谢。