Xml xslt问题(名称空间?)

Xml xslt问题(名称空间?),xml,xslt,xhtml,namespaces,Xml,Xslt,Xhtml,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="htt

我有这样一份文件:

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

但它不起作用

您至少有两个问题:

默认名称空间不同,因此XSL中的模板匹配将不起作用。要么使它们匹配,要么在样式表中提供显式名称空间前缀。 select的值将返回body元素的文本值,这可能不是您想要的。 如果您试图完成的只是将SVG部分输出为SVG doctype,那么请执行以下操作:

Google XSL标识转换,以了解如何从输入到输出进行深度复制。 添加具有doctype public和doctype system属性的标记,指定要输出的doctype信息。 这是未经测试的,但应该非常接近。您必须添加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>

您至少有两个问题:

默认名称空间不同,因此XSL中的模板匹配将不起作用。要么使它们匹配,要么在样式表中提供显式名称空间前缀。 select的值将返回body元素的文本值,这可能不是您想要的。 如果您试图完成的只是将SVG部分输出为SVG doctype,那么请执行以下操作:

Google XSL标识转换,以了解如何从输入到输出进行深度复制。 添加具有doctype public和doctype system属性的标记,指定要输出的doctype信息。 这是未经测试的,但应该非常接近。您必须添加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>

在这种情况下,标识转换是无用的。我会尝试:

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

在本例中,标识转换是无用的。我会尝试:

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

此转换:

应用于提供的XML文档时:

生成所需的结果:

这一转变:

应用于提供的XML文档时:

生成所需的结果:


我应该将其转换为svg文档,如:我应该将其转换为svg文档,如:Good question+1。请参阅我的答案,以获得适用于任何文档结构的完整而简单的解决方案。好问题+1。有关适用于任何文档结构的完整而简单的解决方案,请参见我的答案。