【问题标题】:xslt problem (namespaces?)xslt 问题(命名空间?)
【发布时间】:2010-06-30 16:48:40
【问题描述】:

我有这样的文件:

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

但它不起作用

【问题讨论】:

  • 好问题 (+1)。请参阅我的答案,了解适用于任何文档结构的完整而简单的解决方案。

标签: xml xslt xhtml namespaces


【解决方案1】:

你有(至少)两个问题:

  1. 默认命名空间不同,因此 XSL 中的模板匹配不起作用。要么让它们匹配,要么在样式表中提供明确的命名空间前缀。
  2. value-of-select 将返回 body 元素的文本值,这可能不是您想要的。

如果您想要完成的只是将 SVG 部分输出为 SVG 文档类型,请执行以下操作:

  1. 谷歌“XSL 身份转换”以了解如何从输入到输出进行“深度复制”。
  2. 添加带有doctype-publicdoctype-system 属性的&lt;xsl:output ...&gt; 标记,指定要输出的文档类型信息。

这是未经测试的,但应该非常接近。您必须添加文档类型信息:

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

【讨论】:

  • 我应该将其转换为 svg 文档,例如: ttp://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" rel="nofollow" target="_blank">w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
【解决方案2】:

这种转变

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

【讨论】:

    【解决方案3】:

    在这种情况下,身份转换是没有用的。我会尝试:

    <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:Dimitre 给我们带来了一个有趣的问题。如果输入结构与提供的结构不同怎么办? 一种情况:headbody中有文本节点。我已经根据这两个答案进行了编辑。 其他情况:SVG 在一些 XHTML 标记中。我已经根据这两个答案进行了编辑。 最坏的情况:有几个 svg 元素。在这种情况下,您需要将每个 svg 元素包装成一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      • 2016-04-27
      相关资源
      最近更新 更多