首页 > 解决方案 > How to replace all occurences of an XML tag by its value in an SVG file

问题描述

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.

标签: xsltxmlstarlet

解决方案


Consider utilizing a XSL stylesheet with a template containing the necessary rules. For instance:

strip-tag.xsl

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

source.xml

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>

Transforming the source xml

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

Removing multiple

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.


推荐阅读