Identity transform +

CEHJ
CEHJ used Ask the Experts™
on
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="@*|node()">
                  <xsl:copy>
                            <xsl:apply-templates select="@*|node()"/>
                  </xsl:copy>
        </xsl:template>

</xsl:stylesheet>

I have the above code that does an identity transform on the source, i.e. it outputs the source unchanged. What I want to do is to change all <img src="a.gif" /> to <img src="b.gif" />. Whatever i added to the above including:

<xsl:template match="img">
  XXXXXXXXX
</xsl:template>

seemed to have no effect whatsover. What's the correct code for my template?
                 
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
Firstly it might be a problem of where you have added it in, before or after the identity copy?

Secondly it might be a problem of namespaces. Do you have any?

Top Expert 2016

Author

Commented:
Where should i add it?

This is the declaration in the file i'm attempting to transform:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?xml-stylesheet type="text/xsl" href="q.xsl" ?>
<html xmlns="http://www.w3.org/1999/xhtml">

Commented:
You template for img should be added before that of the copy :-

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

<xsl:template match="img">
 XXXXXXXXX
</xsl:template>

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

</xsl:stylesheet>

I think (it says, trying desparately to remember the exact semantics). If not the switch the two around.
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

Top Expert 2016

Author

Commented:
Sorry - no. That has no effect on the output of <img/> elements whatever.

Commented:
Then its the namespace whioch is the problem.

Change the XSL stylesheet declaration to :-

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

and the template match to :-

<xsl:template match="html:img">
XXXXXXXXX
</xsl:template>

Top Expert 2016

Author

Commented:
You're on to it. Actually i had tried do something about namespaces before but without success. The only thing is that i now have:

<img xmlns="" xmlns:html="http://www.w3.org/1999/xhtml" src="XXXXXXXXX"/>

whereas i want

<img src="XXXXXXXXX"/>

Commented:
OK so you've got the match to work.

We'll try now to make html the default namespace. In the template match REMOVE the html: prefix from img. And in the xsl:stylesheet element REMOVE the :html on the xmlns:html attribute. This should make HTML the default namespace.

Waiting in anticipation!
Top Expert 2016

Author

Commented:
No effect after following alterations:

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





<xsl:template match="img">
  <img src="XXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
</xsl:template>


<xsl:template match="*">
     <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:apply-templates/>
     </xsl:copy>
</xsl:template>

     
</xsl:stylesheet>

Commented:
Now that is VERY strange, since the second template match also uses the same namespace. Perhaps we could try inserting

<xsl:output method="html"/>

which might just surpress the namespace.

Thrilling isn't it?!
Top Expert 2016

Author

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





<xsl:template match="img">
     <xsl:output method="html"/>
            <img src="XXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
     </xsl:output>
</xsl:template>


<xsl:template match="*">
     <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:apply-templates/>
     </xsl:copy>
</xsl:template>

     
</xsl:stylesheet>

Gave the error:

"xsl:output is not allowed in this position in the stylesheet!"

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

<xsl:output method="html"/>


<xsl:template match="img">
     <img src="XXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
</xsl:template>


<xsl:template match="*">
    <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

   
</xsl:stylesheet>


xsl:output is a top level directive.
Top Expert 2016

Author

Commented:
The <img /> template is not activated at all by that.

Commented:
So we've lost the match again. I thing we'll have to go back to the situation before I said REMOVE, but still try the xsl:output. These namespaces can be a real pain!
Top Expert 2016

Author

Commented:
Namespacces back in the output again, despite <xsl:output method="html"/>

Commented:
So now with this sheet change the

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

to

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="#default" version="1.0">


Top Expert 2016

Author

Commented:
This is what i've got now:

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="#default" version="1.0">


<xsl:output method="html"/>



<xsl:template match="html:img">
 <img src="XXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
</xsl:template>


<xsl:template match="*">
    <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

   
</xsl:stylesheet>



Errors are:

Prefix must resolve to a namespace: html

Commented:
The default namespace is not called "html" so the template

<xsl:template match="html:img">

should read

<xsl:template match="img">


Top Expert 2016

Author

Commented:
This is what i've got now:

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="#default" version="1.0">


<xsl:output method="html"/>



<xsl:template match="img">
<img src="XXXXXXXXXXXXX" />
</xsl:template>


<xsl:template match="*">
   <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
   </xsl:copy>
</xsl:template>

   
</xsl:stylesheet>

Template not picked up
Top Expert 2016

Author

Commented:
Thanks for your help

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial