2010-06-30 5 views
2

У меня есть документ, как это:проблема XSLT (с пространствами имен?)

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

я должен извлечь только содержание тела я тред с:

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

но не работают

+0

Хороший вопрос (+1).См. Мой ответ для полного и простого решения, которое работает с любой структурой документа. –

ответ

0

У вас (как минимум) две проблемы:

  1. По умолчанию пространства имен разные, поэтому совпадение шаблона в XSL не будет работать. Либо сделайте их сопряженными, либо предоставите явные префиксы пространства имен в таблице стилей.
  2. Значение значения будет возвращать текстовое значение элемента body, что, вероятно, не является тем, что вы хотите.

Если все, что вы пытаетесь сделать, чтобы вывести SVG часть как SVG DOCTYPE, то сделайте следующее:

  1. Google «XSL Идентичность Transform», чтобы понять, как это сделать «глубокий копировать "со входа на выход.
  2. Добавьте тег <xsl:output ...> с doctype-public и doctype-system атрибутами, указывающими информацию о типе, которую вы хотите выводить.

Это не проверено, но должно быть довольно близко. Вам нужно будет добавить информацию о допите:

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

я должен преобразовать его в SVG документ как: Erick

0

В этом случае преобразования идентичности не используются. Я хотел бы попробовать:

<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: Если вы хотите, чтобы украсить вещи немного:

<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: Димитр приносит нам интересную проблему. Что делать, если структура ввода не похожа на структуру ввода? Один случай: есть текстовые узлы в head или body. Я отредактировал оба ответа. Другой случай: SVG находится внутри некоторой разметки XHTML. Я отредактировал оба ответа. Худший случай: есть несколько элементов svg. В этом случае вам нужно будет обернуть каждый элемент svg в один.

0

Это преобразование:

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

при нанесении на поставленном XML документа:

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

производит желаемого результата:

<!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> 
Смежные вопросы