XSLT条件模板匹配两个属性

时间:2015-03-06 21:25:27

标签: xslt svg

我必须解析这个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属性包含字母L的两倍。这是我得到的:

<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>

预期结果应为(注意Z属性后附加的字母d

<?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>

2 个答案:

答案 0 :(得分:3)

  

我想要实现的,就是将字母Z添加到d属性中   适合两种条件的路径。

然后,您的模板应该匹配@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>

答案 1 :(得分:1)

您遇到的第一个问题是名称空间。 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>