How can I replace all occurences of a given XML tag by its value using xslt template ?
For instance, <tspan x="12.02" y="0">ogen</tspan>
would become ogen
.
I can delete all occurences using this command line:
xmlstarlet ed -N ns=http://www.w3.org/2000/svg -d "//ns:tspan" foo.svg
But I still can't find the way to replace it by its value instead.
Consider utilizing a XSL stylesheet with a template containing the necessary rules. For instance:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="node()[not(name()='tspan')]|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This template matches all nodes and copies them. However the XPath expression defined in the match
attribute, (i.e. the [not(name()='tspan')]
part), exludes any tspan
element nodes and their associated attribute node(s) from being copied - effectively deleting them. Child element nodes and/or text nodes of the tspan
element will be copied, so they'll remain in the output as desired.
Consider the following example source.xml
file:
<?xml version="1.0"?>
<svg width="250" height="40" viewBox="0 0 250 40" xmlns="http://www.w3.org/2000/svg" version="1.1">
<text x="10" y="10">The <tspan x="10" y="10">quick</tspan> brown fox <tspan x="30" y="30">jumps</tspan> over the lazy dog</text>
<a href="https://www.example.com"><text x="100" y="100"><tspan x="50" y="50">click</tspan> me</text></a>
</svg>
Running the following xmlstarlet
command (with the correct paths defined for the files):
$ xml tr path/to/strip-tag.xsl path/to/source.xml
Or running the following xsltproc
command (if your system has it available):
$ xsltproc path/to/strip-tag.xsl path/to/source.xml
will print the following to the console:
<?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg" width="250" height="40" viewBox="0 0 250 40" version="1.1"> <text x="10" y="10">The quick brown fox jumps over the lazy dog</text> <a href="https://www.example.com"><text x="100" y="100">click me</text></a> </svg>
Note: All instances of the opening and closing tspan
tags have been removed.
To remove multiple different named elements utilize the and
operator in the XPath expression defined in the match
attribute. For instance:
<!-- strip-multiple-tags.xsl-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="node()[not(name()='tspan') and not(name()='a')]|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Transforming source.xml
using this template will result in the following output:
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="40" viewBox="0 0 250 40" version="1.1"> <text x="10" y="10">The quick brown fox jumps over the lazy dog</text> <text x="100" y="100">click me</text> </svg>
Note: All instances of both tspan
and a
tags have been removed.