2010-06-30 8 views
2

J'ai un document comme celui-ci:problème xslt (namespaces?)

<?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"> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg= "http://www.w3.org/2000/svg"> 
<body> 
<svg:svg width="500" height="560" version="1.1" > 

... 
... 

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

i doit extraire uniquement le contenu du corps i Tred avec:

<?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"> 
    <xsl:template match="/"> 
     <xsl:value-of select="//body" /> 
    </xsl:template> 
</xsl:stylesheet> 

mais il ne fonctionne pas

+0

Bonne question (+1).Voir ma réponse pour une solution complète et simple qui fonctionne avec n'importe quelle structure de document. –

Répondre

0

Vous avez (au moins) deux problèmes:

  1. La valeur par défaut Les espaces de noms sont différents, donc les correspondances de modèles dans le XSL ne fonctionneront pas. Faites-les correspondre ou fournissez des préfixes d'espace de noms explicites dans la feuille de style.
  2. La valeur-de-select renverra la valeur de texte de l'élément body, ce qui n'est probablement pas ce que vous voulez.

Si tout ce que vous essayez d'accomplir est à la sortie de la partie SVG comme un doctype SVG, puis procédez comme suit:

  1. Google « XSL Identity Transformer » pour comprendre comment faire une « profonde copier "de l'entrée à la sortie.
  2. Ajoutez une balise <xsl:output ...> avec les attributs et doctype-system spécifiant les informations doctype que vous souhaitez obtenir.

Ceci est non testé, mais devrait être assez proche. Vous devrez ajouter les informations doctype:

<?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> 
+0

Je devrais le transformer dans un document svg comme: Erick

0

Dans ce cas, les transformations d'identité ne servent à rien. Je voudrais essayer:

<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: Si vous voulez embellir les choses un peu:

<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"> 
      <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 nous amène un problème intéressant. Que faire si la structure d'entrée n'est pas comme celle qui a été fournie? Un cas: il y a des nœuds de texte dans head ou body. J'ai édité les deux réponses selon. Autre cas: SVG est dans un balisage XHTML. J'ai édité les deux réponses selon. Le pire des cas: il y a plusieurs éléments svg. Dans ce cas, vous devez envelopper chaque élément svg en un.

0

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

lorsqu'il est appliqué sur le document XML fourni:

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

... 
... 

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

produit le résultat recherché:

<!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"> 

... 
... 

</svg:svg>