XSLT 条件模板匹配两个属性
XSLT conditional template match on two attributes
我必须解析这个 SVG 并应用一些转换:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="540pt" height="263pt" viewBox="0 0 540 263" version="1.1">
<g id="surface1">
...
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270 67.160156 L 270.238281 67.640625 L 277.679688 67.640625 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 271.199219 68.839844 L 285.359375 68.839844 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 277.679688 67.640625 L 285.359375 68.839844 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 272.878906 71.238281 L 293.039062 71.238281 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 285.359375 68.839844 L 293.039062 71.238281 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 272.878906 71.238281 L 275.28125 74.601562 L 300 74.601562 "/>
...
</g>
</svg>
我需要一个匹配 path
元素的模板,其中 style
属性包含字符串 fill:rgb(0%,0%,0%)
,d
属性包含两倍的字母 [=21] =].这是我得到的:
<xsl:template match="@style[contains(., 'fill:rgb(0%,0%,0%)')] and @d[string-length() - string-length(translate(., 'L', '')) = 2]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
似乎每个条件都单独起作用,但当在一起时,它就不起作用了。
<xsl:template match="@style[contains(., 'fill:rgb(0%,0%,0%)')]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
和
<xsl:template match="@d[string-length() - string-length(translate(., 'L', '')) = 2]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
此外,path
元素的匹配似乎不起作用...
<xsl:template match="path">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
这是完整的转换文件。问题似乎是 path
元素的匹配。
<?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"/>
<xsl:param name="stroke">black</xsl:param>
<xsl:param name="stroke-width">50px</xsl:param>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|text()|*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="path[@style[contains(., 'fill:rgb(0%,0%,0%)')] and @d[string-length() - string-length(translate(., 'L', '')) = 2]]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
<xsl:template match="@*|text()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
预期结果应该是(注意附加到 d
属性的字母 Z
):
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="540pt" height="263pt" viewBox="0 0 540 263" version="1.1">
<g id="surface1">
...
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270 67.160156 L 270.238281 67.640625 L 277.679688 67.640625 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 271.199219 68.839844 L 285.359375 68.839844 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 277.679688 67.640625 L 285.359375 68.839844 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 272.878906 71.238281 L 293.039062 71.238281 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 285.359375 68.839844 L 293.039062 71.238281 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 272.878906 71.238281 L 275.28125 74.601562 L 300 74.601562 Z"/>
...
</g>
</svg>
您遇到的第一个问题是名称空间。 XML 输入中的元素是命名空间
的一部分
<svg xmlns="http://www.w3.org/2000/svg"
这意味着您也需要在 XSLT 中引用该命名空间....
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:svg="http://www.w3.org/2000/svg">
然后你在模板匹配中使用这个前缀
<xsl:template match="svg:path">
现在,您实际上想要在此处匹配 d
属性,因此您的模板将如下所示
<xsl:template match="svg:path[contains(@style, 'fill:rgb(0%,0%,0%)')]
/@d[string-length() - string-length(translate(., 'L', '')) = 2]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
All I want to achieve, is to add the letter Z to the d attribute of
the paths that fit both conditions.
那么你的模板应该匹配 @d
属性或其父元素 path
- 而不是它的兄弟 @style
属性,就像你现在拥有的那样(更不用说你的语法无效)。
这样试试,也许:
<xsl:template match="@d[string-length() - string-length(translate(., 'L', '')) = 2] [contains(../@style, 'fill:rgb(0%,0%,0%)')]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
我必须解析这个 SVG 并应用一些转换:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="540pt" height="263pt" viewBox="0 0 540 263" version="1.1">
<g id="surface1">
...
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270 67.160156 L 270.238281 67.640625 L 277.679688 67.640625 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 271.199219 68.839844 L 285.359375 68.839844 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 277.679688 67.640625 L 285.359375 68.839844 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 272.878906 71.238281 L 293.039062 71.238281 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 285.359375 68.839844 L 293.039062 71.238281 "/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 272.878906 71.238281 L 275.28125 74.601562 L 300 74.601562 "/>
...
</g>
</svg>
我需要一个匹配 path
元素的模板,其中 style
属性包含字符串 fill:rgb(0%,0%,0%)
,d
属性包含两倍的字母 [=21] =].这是我得到的:
<xsl:template match="@style[contains(., 'fill:rgb(0%,0%,0%)')] and @d[string-length() - string-length(translate(., 'L', '')) = 2]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
似乎每个条件都单独起作用,但当在一起时,它就不起作用了。
<xsl:template match="@style[contains(., 'fill:rgb(0%,0%,0%)')]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
和
<xsl:template match="@d[string-length() - string-length(translate(., 'L', '')) = 2]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
此外,path
元素的匹配似乎不起作用...
<xsl:template match="path">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
这是完整的转换文件。问题似乎是 path
元素的匹配。
<?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"/>
<xsl:param name="stroke">black</xsl:param>
<xsl:param name="stroke-width">50px</xsl:param>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|text()|*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="path[@style[contains(., 'fill:rgb(0%,0%,0%)')] and @d[string-length() - string-length(translate(., 'L', '')) = 2]]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
<xsl:template match="@*|text()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
预期结果应该是(注意附加到 d
属性的字母 Z
):
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="540pt" height="263pt" viewBox="0 0 540 263" version="1.1">
<g id="surface1">
...
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270 67.160156 L 270.238281 67.640625 L 277.679688 67.640625 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 271.199219 68.839844 L 285.359375 68.839844 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 270.238281 67.640625 L 277.679688 67.640625 L 285.359375 68.839844 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 272.878906 71.238281 L 293.039062 71.238281 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 271.199219 68.839844 L 285.359375 68.839844 L 293.039062 71.238281 Z"/>
<path style=" stroke:black;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 272.878906 71.238281 L 275.28125 74.601562 L 300 74.601562 Z"/>
...
</g>
</svg>
您遇到的第一个问题是名称空间。 XML 输入中的元素是命名空间
的一部分<svg xmlns="http://www.w3.org/2000/svg"
这意味着您也需要在 XSLT 中引用该命名空间....
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:svg="http://www.w3.org/2000/svg">
然后你在模板匹配中使用这个前缀
<xsl:template match="svg:path">
现在,您实际上想要在此处匹配 d
属性,因此您的模板将如下所示
<xsl:template match="svg:path[contains(@style, 'fill:rgb(0%,0%,0%)')]
/@d[string-length() - string-length(translate(., 'L', '')) = 2]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>
All I want to achieve, is to add the letter Z to the d attribute of the paths that fit both conditions.
那么你的模板应该匹配 @d
属性或其父元素 path
- 而不是它的兄弟 @style
属性,就像你现在拥有的那样(更不用说你的语法无效)。
这样试试,也许:
<xsl:template match="@d[string-length() - string-length(translate(., 'L', '')) = 2] [contains(../@style, 'fill:rgb(0%,0%,0%)')]">
<xsl:attribute name="d">
<xsl:value-of select="."/>
<xsl:text>Z</xsl:text>
</xsl:attribute>
</xsl:template>