Remove namespace declaration from XSLT stylesheet with XSLT

前端 未结 1 1020
独厮守ぢ
独厮守ぢ 2020-12-11 21:41

I have an XSLT stylesheet like the following:




        
相关标签:
1条回答
  • 2020-12-11 22:15

    I would add

     exclude-result-prefixes="foo"
    

    onto your

     <xsl:stylesheet>
    

    element. Then the namespace declaration for foo will be omitted if possible, i.e. if there no elements or attributes in that namespace to output.

    FYI, the reason tnat this line

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

    throws an error is because xmlns:foo in the input document is not an attribute; it's a pseudoattribute. What your match pattern is asking to match is an attribute named foo that is in a namespace corresponding to a namespace prefix xmlns. Since you have not declared a namespace prefix xmlns in your stylesheet, you get the error "prefix xmlns is not defined."

    Update:

    I see from your posted output (and my own testing) that exclude-result-prefixes hasn't been effective in removing the namespace declaration.

    1) First I would ask why it matters. It doesn't change the namespace of anything in your output XSLT. Are you just trying to remove it for aesthetic reasons?

    2) Looking at the XSLT 1.0 spec, it appears to me that <xsl:copy> pays no attention to 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, only literal result elements will omit namespace nodes based on exclude-result-prefixes.

    On that basis, I would try replacing <xsl:copy> in your identity template (for elements) with <xsl:element name="{name()}"> or some variant thereof. You would then need a separate identity template for non-element nodes.

    I replaced your identity template with the following two templates:

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

    and that gave what I believe is the desired output, with no extraneous ns declarations:

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

    (I have adjusted the whitespace for clarity.)

    0 讨论(0)
提交回复
热议问题