Add attribute to tag with XSLT

2019-05-04 19:22发布

I have a few svg documents with a 1-n Path elements now i wanted to change the color of those path elements.

i have haven't found a way to do this

Svg example document:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="45" width="45" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<g transform="matrix(1.25,0,0,-1.25,0,45)">
<path d="m9 18h18v-3h-18v3"/>
</g>
</svg>

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' version='1.0'>
<xsl:template match='path'>
<xsl:copy>
<xsl:attribute name='fill'>red</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

What do i need to change to make it add/change the fill attribute to red?

标签: xslt
1条回答
时光不老,我们不散
2楼-- · 2019-05-04 19:53

I think you misunderstand how XSLT works. It takes an input XML tree and produces a new tree by interpreting your stylesheet. In other words, your stylesheet defines how a completely new tree is produced from scratch, based on the input XML tree.

It's important to understand that you are not modifying the original XML tree. It's like a difference between a purely functional and imperative language. Bottom line: you can't change the fill attribute to red, you can produce a copy of your original document where the fill attribute is set to red.

That said, this is more or less how you would do it:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:svg="http://www.w3.org/2000/svg" version='1.0'>
    <!-- this template is applied by default to all nodes and attributes -->
    <xsl:template match="@*|node()">
        <!-- just copy all my attributes and child nodes, except if there's a better template for some of them -->
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- this template is applied to an existing fill attribute -->
    <xsl:template match="svg:path/@fill">
        <!-- produce a fill attribute with content "red" -->
        <xsl:attribute name="fill">red</xsl:attribute>
    </xsl:template>

    <!-- this template is applied to a path node that doesn't have a fill attribute -->
    <xsl:template match="svg:path[not(@fill)]">
        <!-- copy me and my attributes and my subnodes, applying templates as necessary, and add a fill attribute set to red -->
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:attribute name="fill">red</xsl:attribute>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
查看更多
登录 后发表回答