使用XSLT从XSLT样式表中删除名称空间声明

前端之家收集整理的这篇文章主要介绍了使用XSLT从XSLT样式表中删除名称空间声明前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个类似于以下的XSLT样式表:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
                  xmlns:saxon="http://saxon.sf.net/">

  <saxon:script language="java" implements-prefix="XQHeaderFunc" src="java:com.sonicsw.xq.service.xform.HeaderExtension" />

  <xsl:output indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:variable name="processId" select="XQHeaderFunc:getProperty(XQHeaderFunc:new(),'processId',-1)" />
    <xsl:value-of select="XQHeaderFunc:setProperty(XQHeaderFunc:new(),string(@id),-1)"/>

    <root>
      <xsl:apply-templates />
    </root>

  </xsl:template>

  <!-- Other stuff -->

</xsl:stylesheet>

我想使用第二个XSLT样式表来转换此样式表,以删除与XQHeaderFunc和saxon命名空间有关的任何内容.有没有办法可以做到这一点?

我现在尝试了以下,成功处理元素,但命名空间声明似乎不想消失.

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
                xmlns:saxon="http://saxon.sf.net/"
                exclude-result-prefixes="XQHeaderFunc saxon">

  <xsl:param name="XQHeaderReplacement" />
  <xsl:variable name="apos">'</xsl:variable>

  <!-- Copy all nodes -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Remove saxon script tag -->
  <xsl:template match="saxon:script" />

  <!-- Remove elements with setProperty calls -->
  <xsl:template match="*[starts-with(@select,'XQHeaderFunc:setProperty')]" />

  <!-- Replace getProperty calls with replacement value-->
  <xsl:template match="@select[starts-with(.,'XQHeaderFunc:getProperty')]">
      <xsl:attribute name="select">
        <xsl:value-of select="concat($apos,$XQHeaderReplacement,$apos)"/>
      </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

输出

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension" 
                xmlns:saxon="http://saxon.sf.net/">

  <xsl:output indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/">
    <xsl:variable name="processId" select="''" />


    <root>
      <xsl:apply-templates />
    </root>

  </xsl:template>

  <!-- Other stuff -->

</xsl:stylesheet>
我想补充一下
exclude-result-prefixes="foo"

到你的

<xsl:stylesheet>

元件.然后,如果可能,将省略foo的名称空间声明,即如果该名称空间中没有要输出的元素或属性.

仅供参考,原因是这条线

<xsl:template match="xsl:stylesheet/@xmlns:foo" />`

抛出错误是因为输入文档中的xmlns:foo不是属性;这是一个伪属性.您的匹配模式要求匹配的是名为foo的属性,该属性位于与命名空间前缀xmlns对应的命名空间中.由于尚未在样式表中声明名称空间前缀xmlns,因此会出现错误“未定义前缀xmlns”.

更新:

我从你发布的输出(以及我自己的测试)中看到,exclude-result-prefixes在删除命名空间声明时没有效果.

1)首先我会问为什么这很重要.它不会更改输出XSLT中任何内容的命名空间.你是否只是出于审美原因试图将其删除

2)查看XSLT 1.0 spec,it appears to me< xsl:copy>不关注exclude-result-prefixes:

Instantiating the xsl:copy element creates a copy of the current node.
The namespace nodes of the current node are automatically copied as
well…

AFAICT,只有文字结果元素将基于exclude-result-prefixs省略命名空间节点.

在此基础上,我会尝试替换< xsl:copy>在您的身份模板(对于元素)中使用< xsl:element name =“{name()}”>或其某些变体.然后,您需要为非元素节点使用单独的标识模板.

我用以下两个模板替换了您的身份模板:

<!-- Copy elements -->
<xsl:template match="*" priority="-1">
   <xsl:element name="{name()}">
      <xsl:apply-templates select="node()|@*"/>
   </xsl:element>
</xsl:template>

<!-- Copy all other nodes -->
<xsl:template match="node()|@*" priority="-2">
   <xsl:copy />      
</xsl:template>

这给了我认为是理想的输出,没有多余的ns声明:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output indent="yes" omit-xml-declaration="yes" />

   <xsl:template match="/">
      <xsl:variable name="processId" select="''" />
      <root>
         <xsl:apply-templates />
      </root>
   </xsl:template>

   <!-- Other stuff -->
</xsl:stylesheet>

(为了清晰起见,我调整了空白.)

猜你在找的XML相关文章