XSLT: Add namespace to root element

前端 未结 2 1288
灰色年华
灰色年华 2020-12-09 13:28

I need to change namespaces in the root element as follows:

input document:


<         


        
相关标签:
2条回答
  • 2020-12-09 13:56

    XSLT 2.0 isn't necessary to solve this problem.

    Here is an XSLT 1.0 solution, which works equally well as XSLT 2.0 (just change the version attribute to 2.0):

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     exclude-result-prefixes="xlink"
     >
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="/*">
       <xsl:element name="{name()}" namespace="{namespace-uri()}">
    
          <xsl:copy-of select=
            "namespace::*
               [not(name()='ns2')
              and
                not(name()='')
               ]"/>
    
          <xsl:copy-of select=
           "document('')/*/namespace::*[name()='xlink']"/>
    
          <xsl:copy-of select="@*"/>
    
          <xsl:attribute name="audience">external</xsl:attribute>
       </xsl:element>
     </xsl:template>
    </xsl:stylesheet>
    

    When the above transformation is applied on this XML document:

    <foo
    xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
    xmlns:ns2="http://www.w3.org/1999/xlink"
    xmlns="urn:isbn:1-931666-22-9"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    

    the wanted result is produced:

    <foo xmlns="urn:isbn:1-931666-22-9"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
         audience="external"/>
    
    0 讨论(0)
  • 2020-12-09 14:03

    You should really be using the "identity template" for this, and you should always have it on hand. Create an XSLT with that template, call it "identity.xslt", then into the current XSLT. Assume the prefix "bad" for the namespace you want to replace, and "good" for the one you want to replace it with, then all you need is a template like this (I'm at work, so forgive the formatting; I'll get back to this when I'm at home): ... If that doesn't work in XSLT 1.0, use a match expression like "*[namespace-uri() = 'urn:bad-namespace'", and follow Dimitre's instructions for creating a new element programmatically. Within , you really need to just apply-template recursively...but really, read up on the identity template.

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