views:

39

answers:

3

I have a document like this:

<?xml-stylesheet type="text/css" href="http://ltw1001.web.cs.unibo.it/svg.css" encoding="UTF-8"?>
<!DOCTYPE html  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg= "http://www.w3.org/2000/svg"&gt;
<body>
<svg:svg width="500" height="560" version="1.1" >

...
...

</svg:svg></body></html>

i should extract only the content of body i tred with:

<?xml version="1.0" standalone="no"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/HTML/1998/html4"&gt;
    <xsl:template match="/">
        <xsl:value-of select="//body" />
    </xsl:template>
</xsl:stylesheet>

but it don't work

A: 

You have (at least) two problems:

  1. The default namespaces are different, so the template matches in the XSL won't work. Either make them match or provide explicit namespace prefixes in the stylesheet.
  2. The value-of-select will return the text value of the body element, which is probably not what you want.

If all you're trying to accomplish is to output the SVG part as an SVG doctype, then do the following:

  1. Google "XSL Identity Transform" to understand how to do a "deep copy" from the input to the output.
  2. Add an <xsl:output ...> tag with doctype-public and doctype-system attributes specifying the doctype information you want output.

This is untested, but should be pretty close. You'll have to add the doctype info:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:svg= "http://www.w3.org/2000/svg"
  version="2.0">

  <xsl:output method="xml" doctype-public="..." doctype-system="..."/>

  <xsl:template match="/">
    <xsl:apply-templates select="//svg:svg"/>    
  </xsl:template>

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

</xsl:stylesheet>
Jim Garrison
i should transform it in a svg document like:<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg:svg ........</svg:svg>
Erick
A: 

In this case, the identity transforms is for no use. I would try:

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

  <xsl:output method="xml" doctype-public="-//W3C//DTD SVG 1.1//EN" doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" /> 

  <xsl:template match="/"> 
    <xsl:copy-of select="/*/xhtml:body//svg:svg"/>     
  </xsl:template> 

</xsl:stylesheet> 

EDIT: If you want to beautify things a bit:

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

    <xsl:output method="xml" doctype-public="-//W3C//DTD SVG 1.1//EN" doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" />

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

    <xsl:template match="svg:svg">
        <xsl:call-template name="svg"/>
    </xsl:template>

    <xsl:template match="svg:*" mode="svg" name="svg">
        <xsl:element name="{substring-after(name(),':')}" namespace="http://www.w3.org/2000/svg"&gt;
            <xsl:apply-templates select="@*|node()" mode="svg"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*" mode="svg">
        <xsl:copy/>
    </xsl:template>
</xsl:stylesheet>

Edit 2: Dimitre brings us an interesting problem. What if the input structure isn't like the one that was provided? One case: there are text nodes in head or body. I've edited both answer according. Other case: SVG is inside some XHTML markup. I've edited both answer according. Worst case: there are several svg elements. In this case you would need to wrap every each svg element into one.

Alejandro
A: 

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xhtml="http://www.w3.org/1999/xhtml"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"
  doctype-public="-//W3C//DTD SVG 1.1//EN"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="*[not(descendant::xhtml:body)]"/>

 <xsl:template match="*[descendant::xhtml:body]">
  <xsl:apply-templates select="*"/>
 </xsl:template>

 <xsl:template match="xhtml:body" priority="20">
   <xsl:copy-of select="node()"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg= "http://www.w3.org/2000/svg"&gt;
<body>
<svg:svg width="500" height="560" version="1.1" >

...
...

</svg:svg></body></html>

produces the wanted result:

<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD SVG 1.1//EN">
<svg:svg width="500" height="560" version="1.1" xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg"&gt;

...
...

</svg:svg>
Dimitre Novatchev