проблема xslt (пространства имен?) - PullRequest
2 голосов
/ 30 июня 2010

У меня есть такой документ:

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

, но он не работает

Ответы [ 3 ]

0 голосов
/ 30 июня 2010

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

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

РЕДАКТИРОВАТЬ : Если вы хотите немного украсить вещи:

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

Редактировать 2 : Димитр приносит нам интересную проблему. Что если структура ввода не похожа на ту, которая была предоставлена? Один случай: в head или body есть текстовые узлы. Я отредактировал оба ответа соответственно. Другой случай: SVG находится внутри некоторой разметки XHTML. Я отредактировал оба ответа соответственно. В худшем случае: есть несколько svg элементов. В этом случае вам нужно будет обернуть каждый элемент svg в один.

0 голосов
/ 30 июня 2010

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

<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>
0 голосов
/ 30 июня 2010

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

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

Если все, что вы пытаетесь сделать, это вывести часть SVG в виде SVG-документа, то выполните следующие действия:

  1. Google "XSL Identity 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>
...