XSLT - 在应用其他模板之前更新原始 xml 的命名空间

XSLT - Update namespaces of the original xml before applying other templates

我有一个 xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<mdb:MD_Metadata xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/1.0"
   xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/1.0"
   xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0"
   xmlns:mcc="http://standards.iso.org/iso/19115/-3/mcc/1.0"  
   xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0">
   <mdb:metadataIdentifier>
       <mcc:MD_Identifier>
           <mcc:authority>
               <cit:CI_Citation>
                   <cit:title>
                       <gco:CharacterString>Old UUID</gco:CharacterString>
                   </cit:title>
               </cit:CI_Citation>
           </mcc:authority>
           <mcc:code>
               <gco:CharacterString>3796749d-c8a5-46ae-af11-24a977cb1d9a</gco:CharacterString>
           </mcc:code>
           <mcc:codeSpace>
               <gco:CharacterString>urn:uuid</gco:CharacterString>
           </mcc:codeSpace>
       </mcc:MD_Identifier>
   </mdb:metadataIdentifier>
</mdb:MD_Metadata>

我想在应用其他模板之前更新名称空间(mdb 和 cit to2.0):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:cit1="http://standards.iso.org/iso/19115/-3/cit/1.0"
        xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"
        xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0"
        xmlns:mcc="http://standards.iso.org/iso/19115/-3/mcc/1.0"
        xmlns:mco="http://standards.iso.org/iso/19115/-3/mco/1.0"
        xmlns:mda="http://standards.iso.org/iso/19115/-3/mda/1.0"
        xmlns:mdb1="http://standards.iso.org/iso/19115/-3/mdb/1.0"
        xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"
        xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0"
        xmlns:gcx="http://standards.iso.org/iso/19115/-3/gcx/1.0"
        xmlns:gml="http://www.opengis.net/gml/3.2"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
        exclude-result-prefixes="#all">
 
        <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
        <xsl:strip-space elements="*"/>

        <xsl:template match="mdb1:*">
            <xsl:element name="{name()}" namespace="http://standards.iso.org/iso/19115/-3/mdb/2.0">
                <xsl:if test="count(ancestor::*) = 0">
                    <xsl:call-template name="add-iso19115-3.2018-namespaces"/>
                </xsl:if>
            </xsl:element>
        </xsl:template>
        <xsl:template match="cit1:*" >
            <xsl:element name="{name()}" namespace="http://standards.iso.org/iso/19115/-3/cit/2.0">
                <xsl:apply-templates select="@*|*"/>
            </xsl:element>
        </xsl:template>
        

        <xsl:template match="/">
            <xsl:apply-templates/>
        </xsl:template>


    <!--Identity template that will copy every attribute, element, comment, and processing instruction to the output-->
    <xsl:template match="@*|node()">
        <xsl:copy copy-namespaces="no">
            <!-- Including any attributes it has and any child nodes -->
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

        <xsl:template match="mdb:MD_Metadata" mode="main">
            <xsl:copy>
                <xsl:apply-templates select="@* , node()"/>
                <!-- add mdb:defaultLocale after mdb:metadataIdentifier -->
                <mdb:defaultLocale>
                    <lan:PT_Locale id="EN">
                        <lan:language>
                            <lan:LanguageCode codeList="http://www.loc.gov/standards/iso639-2/" codeListValue="eng"/>
                        </lan:language>
                        <lan:characterEncoding>
                            <lan:MD_CharacterSetCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8"/>
                        </lan:characterEncoding>
                    </lan:PT_Locale>
                </mdb:defaultLocale>
            </xsl:copy>
        </xsl:template>
    
        <!-- replace cit:title -->
        <xsl:template match="mdb:metadataIdentifier/mcc:MD_Identifier/mcc:authority/cit:CI_Citation/cit:title/gco:CharacterString/text()">
            <xsl:value-of select="'UUID Test'"/>
        </xsl:template>

        <!-- add mcc:description -->
        <xsl:template match="mdb:metadataIdentifier/mcc:MD_Identifier">
            <xsl:apply-templates/>
            <mcc:description>
                <gco:CharacterString>Data was submitted
                </gco:CharacterString>
            </mcc:description>
        </xsl:template>

        <!-- update attribute 'codeLIst' value of  mdb:metadataScope > mdb:MD_MetadataScope > mdb:resourceScope > mcc:MD_ScopeCode -->
        <xsl:template match="mdb:metadataScope/mdb:MD_MetadataScope/mdb:resourceScope/mcc:MD_ScopeCode">
            <xsl:if test="@codeListValue">
                <xsl:attribute name="codeList">
                    <xsl:value-of select="'https://schemas.isotc211.org/19115/resources/Codelist/cat/codelists.xml#MD_ScopeCode'" />
                </xsl:attribute>
            </xsl:if>
        </xsl:template>
    
    <xsl:template name="add-iso19115-3.2018-namespaces">
        <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
        <xsl:namespace name="cit" select="'http://standards.iso.org/iso/19115/-3/cit/2.0'"/>
        <xsl:namespace name="lan" select="'http://standards.iso.org/iso/19115/-3/lan/1.0'"/>
        <xsl:namespace name="mcc" select="'http://standards.iso.org/iso/19115/-3/mcc/1.0'"/>
        <xsl:namespace name="gco" select="'http://standards.iso.org/iso/19115/-3/gco/1.0'"/>
        <xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
    </xsl:template>

</xsl:stylesheet>

只有当原始文件中与 mdb 和 cit 关联的命名空间如下所示时,上面的样式表才有效:

<mdb:MD_Metadata xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"
    xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"
    xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0"
    xmlns:mcc="http://standards.iso.org/iso/19115/-3/mcc/1.0"  
    xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0">
....

我如何才能先更新命名空间,然后再根据更新的 xml 应用其余模板?

也许以下是您想要的,在一个转换步骤中执行名称空间转换和其他更改:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:cit1="http://standards.iso.org/iso/19115/-3/cit/1.0"
        xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"
        xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0"
        xmlns:mcc="http://standards.iso.org/iso/19115/-3/mcc/1.0"
        xmlns:mco="http://standards.iso.org/iso/19115/-3/mco/1.0"
        xmlns:mda="http://standards.iso.org/iso/19115/-3/mda/1.0"
        xmlns:mdb1="http://standards.iso.org/iso/19115/-3/mdb/1.0"
        xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"
        xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0"
        xmlns:gcx="http://standards.iso.org/iso/19115/-3/gcx/1.0"
        xmlns:gml="http://www.opengis.net/gml/3.2"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
        exclude-result-prefixes="#all">

  <xsl:output method="xml" indent="yes"/>
  
    <!--Identity template that will copy every attribute, element, comment, and processing instruction to the output-->
    <xsl:template match="@*|node()">
        <xsl:copy copy-namespaces="no">
            <!-- Including any attributes it has and any child nodes -->
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
 
  <xsl:template match="/mdb1:*">
    <xsl:element name="mdb:{local-name()}">
      <xsl:call-template name="add-iso19115-3.2018-namespaces"/>
      <xsl:apply-templates select="@* , node()"/>
    </xsl:element>
  </xsl:template> 
  
  <xsl:template match="mdb1:*">
    <xsl:element name="mdb:{local-name()}">
      <xsl:apply-templates select="@* , node()"/>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="cit1:*">
    <xsl:element name="cit:{local-name()}">
      <xsl:apply-templates select="@* , node()"/>
    </xsl:element>
  </xsl:template>
  
       <xsl:template match="mdb1:MD_Metadata">
            <xsl:copy>
                <xsl:apply-templates select="@* , node()"/>
                <!-- add mdb:defaultLocale after mdb:metadataIdentifier -->
                <mdb:defaultLocale>
                    <lan:PT_Locale id="EN">
                        <lan:language>
                            <lan:LanguageCode codeList="http://www.loc.gov/standards/iso639-2/" codeListValue="eng"/>
                        </lan:language>
                        <lan:characterEncoding>
                            <lan:MD_CharacterSetCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8"/>
                        </lan:characterEncoding>
                    </lan:PT_Locale>
                </mdb:defaultLocale>
            </xsl:copy>
        </xsl:template>
    
        <!-- replace cit:title -->
        <xsl:template match="mdb1:metadataIdentifier/mcc:MD_Identifier/mcc:authority/cit1:CI_Citation/cit1:title/gco:CharacterString/text()">
            <xsl:value-of select="'UUID Test'"/>
        </xsl:template>

        <!-- add mcc:description -->
        <xsl:template match="mdb1:metadataIdentifier/mcc:MD_Identifier">
            <xsl:apply-templates/>
            <mcc:description>
                <gco:CharacterString>Data was submitted
                </gco:CharacterString>
            </mcc:description>
        </xsl:template>

        <!-- update attribute 'codeLIst' value of  mdb:metadataScope > mdb:MD_MetadataScope > mdb:resourceScope > mcc:MD_ScopeCode -->
        <xsl:template match="mdb1:metadataScope/mdb1:MD_MetadataScope/mdb1:resourceScope/mcc:MD_ScopeCode">
            <xsl:if test="@codeListValue">
                <xsl:attribute name="codeList">
                    <xsl:value-of select="'https://schemas.isotc211.org/19115/resources/Codelist/cat/codelists.xml#MD_ScopeCode'" />
                </xsl:attribute>
            </xsl:if>
        </xsl:template>

    <xsl:template name="add-iso19115-3.2018-namespaces">
        <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
        <xsl:namespace name="cit" select="'http://standards.iso.org/iso/19115/-3/cit/2.0'"/>
        <xsl:namespace name="lan" select="'http://standards.iso.org/iso/19115/-3/lan/1.0'"/>
        <xsl:namespace name="mcc" select="'http://standards.iso.org/iso/19115/-3/mcc/1.0'"/>
        <xsl:namespace name="gco" select="'http://standards.iso.org/iso/19115/-3/gco/1.0'"/>
        <xsl:namespace name="xlink" select="'http://www.w3.org/1999/xlink'"/>
    </xsl:template>


</xsl:stylesheet>