2

Why do I get the xmlns=""? I've tried putting the namespace in many other places and messed with the prefix but can't seem to remove the empty xmlns="" attributes.

XML:

<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
   <CstmrCdtTrfInitn>
      <GrpHdr>
         <MsgId>15957</MsgId>
         <CreDtTm>2025-05-14T03:03:11.917-07:00</CreDtTm>
         <NbOfTxs>3</NbOfTxs>
         <CtrlSum>30</CtrlSum>
         <InitgPty>
            <Nm>GtmtpTest</Nm>
         </InitgPty>
      </GrpHdr>
      <PmtInf>
         <PmtInfId>159571</PmtInfId>
         <PmtMtd>TRF</PmtMtd>
         <BtchBookg>false</BtchBookg>
         <NbOfTxs>3</NbOfTxs>
         <CtrlSum>30</CtrlSum>
         <PmtTpInf>
            <InstrPrty>NORM</InstrPrty>
            <LclInstrm>
               <Cd>STANDARD</Cd>
            </LclInstrm>
         </PmtTpInf>
         <ReqdExctnDt>
            <Dt>2025-05-14</Dt>
         </ReqdExctnDt>
...

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:this="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09"
     exclude-result-prefixes="xs"
     version="3.0">
   
    <xsl:namespace-alias stylesheet-prefix="this" result-prefix=""/>
    
  
    <xsl:mode streamable="yes" on-no-match="shallow-copy"/>
    
    <xsl:template match="this:PmtTpInf" >
        <xsl:apply-templates select="copy-of()" mode="in-memory"/>
    </xsl:template>
    
    <xsl:template match="this:PmtTpInf" mode="in-memory">
        <this:First_Name><xsl:value-of select="'BUSINESS'"/></this:First_Name>
        <this:Last_Name><xsl:value-of select="'MAN'"/></this:Last_Name>
    </xsl:template>
        
</xsl:stylesheet>

Output:

<?xml version="1.0" encoding="UTF-8"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
   <CstmrCdtTrfInitn>
      <GrpHdr>
         <MsgId>15957</MsgId>
         <CreDtTm>2025-05-14T03:03:11.917-07:00</CreDtTm>
         <NbOfTxs>3</NbOfTxs>
         <CtrlSum>30</CtrlSum>
         <InitgPty>
            <Nm>GtmtpTest</Nm>
         </InitgPty>
      </GrpHdr>
      <PmtInf>
         <PmtInfId>159571</PmtInfId>
         <PmtMtd>TRF</PmtMtd>
         <BtchBookg>false</BtchBookg>
         <NbOfTxs>3</NbOfTxs>
         <CtrlSum>30</CtrlSum>
         <First_Name xmlns="">BUSINESS</First_Name><Last_Name xmlns="">MAN</Last_Name>
         <ReqdExctnDt>
            <Dt>2025-05-14</Dt>
         </ReqdExctnDt>
1
  • 1
    Unless you don't need xsl:namespace-alias, as the posted answer suggests, I think you want e.g. xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09" and <xsl:namespace-alias stylesheet-prefix="this" result-prefix="#default"/> but I am not sure Saxon gets it right then. Not sure what is going on. There are some test cases for result-prefix="#default" that do work. Commented May 19 at 18:14

2 Answers 2

3

The answer to the question:

Why do I get the xmlns=""?

is: because you are writing an element to the output whose name is in no namespace, and the serialiser has to generate xmlns="" to stop it being in the default namespace of its parent element. The serializer of course is assuming that you actually intended the element to be in no namespace, which is probably not the case.

Your code writes the element as

<this:First_Name><xsl:value-of select="'BUSINESS'"/></this:First_Name>

and then aliases the namespace "this" to result-prefix="". The spec isn't 100% explicit about whether this is allowed or what it should mean, but a reasonable interpretation is that this should be aliased to the default namespace, which in your case is "no namespace". So you have explicitly asked for the element created by <this:First> to go in no namespace, and the serializer has respected your request by generating xmlns="".

Sign up to request clarification or add additional context in comments.

Comments

1

I suspect the cause is your xsl:namespace-alias declaration which makes no sense to me.

If I understand your goal correctly, all you need to do is:

XSLT 3.0

<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09"
xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
   
<xsl:mode on-no-match="shallow-copy"/>
    
<xsl:template match="PmtTpInf" >
    <First_Name>BUSINESS</First_Name>
    <Last_Name>MAN</Last_Name>
</xsl:template>

</xsl:stylesheet>

The xpath-default-namespace declaration allows you to target the input XML's elements without having to use a prefix.
https://www.w3.org/TR/xslt-30/#unprefixed-qnames

The xmlns declaration creates a default namespace for the literal result elements created in the stylesheet itself:
https://www.w3.org/TR/xslt-30/#literal-result-element

In short, one is for the input and the other for the output.

2 Comments

Thank you! Yours is so much simpler. Are you able to explain Why I need to declare the default namespace and the xmlns?
See the addition to my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.