membersound
membersound

Reputation: 86865

XSLT replacement with namespaces?

If I have an xml with namespaces and want to apply some values replacement, what do I have to change? http://xslt.online-toolz.com/tools/xslt-transformation.php

<?xml version="1.0"?>
<accounts>
<account>
<name>Alex</name>
</account>
<account>
<name>Fiona</name>
</account>
</accounts>

This will change alle name values to "Johndoe":

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
 </xsl:template>

  <xsl:template match="account/name/text()">
   <xsl:text>JohnDoe</xsl:text>
  </xsl:template>
</xsl:stylesheet>

But what if I have a namespace before very tag, like:

<?xml version="1.0"?>
<my:accounts>
<my:account>
<my:name>Alex</my:name>
</my:account>
<my:account>
<my:name>Fiona</my:name>
</my:account>
</my:accounts>

Upvotes: 1

Views: 103

Answers (1)

Flynn1179
Flynn1179

Reputation: 12075

Two ways of doing this. Either include the 'my' namespace in the stylesheet tag like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="(insertnamespacehere)">

and do

<xsl:template match="my:account/my:name/text()">

or do the rather clumsier:

<xsl:template match="*[local-name()='account']/*[local-name()='name']/text()">

I'd be inclined to discourage the latter approach though- namespaces exist to distinguish between elements that have the same local name (such as employee:name and company:name for example), by using local-name() you ignore that distinction. In other words, if your document happens to contains foo:account/foo:name, you'll accidentally replace that too.

Incidentally, your last sample XML isn't valid- the my namespace is not declared. Your root my:accounts would need to include this with <my:accounts xlmns:my="(insertnamespacehere)">

Upvotes: 2

Related Questions