Моя цель — получить выходной XML-файл, в котором первые два узла имеют пространство имен, как показано ниже.
<tp:Редакция>2.0.10</tp:Редакция> <tp:Заголовок>
и from message и все его дочерние узлы имеют префикс пространства имен в виде заголовка:имя элемента.
Ниже мой входной XML:
<DataPDU xmlns = "urn:swift:saa:xsd:saa.2.0">
<Revision>2.0.10</Revision>
<Header>
<Message>
<SenderReference>112712406</SenderReference>
<MessageIdentifier>pacs.008.001.08</MessageIdentifier>
<Format>MX</Format>
<SubFormat>Input</SubFormat>
<Sender>
<DN>ou=xxx,o=ctbaau2s,o=swift</DN>
<FullName>
<X1>CTBAAU2SFXD</X1>
</FullName>
</Sender>
<Receiver>
<DN>ou=xxx,o=testcsns,o=swift</DN>
<FullName>
<X1>TESTCSNSSFXXX</X1>
</FullName>
</Receiver>
<InterfaceInfo>
<UserReference>M13782445</UserReference>
</InterfaceInfo>
<NetworkInfo>
<SWIFTNetNetworkInfo>
<RequestType>pacs.008.001.08</RequestType>
<RequestSubtype>swift.cbprplus.02</RequestSubtype>
</SWIFTNetNetworkInfo>
</NetworkInfo>
</Message>
</Header>
<Body>
<AppHdr xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<Fr>
<FIId>
<FinInstnId>
<BICFI>CTBAAU2SFXD</BICFI>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<BICFI>TESTCSNSSFXXX</BICFI>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>M13782445</BizMsgIdr>
<MsgDefIdr>pacs.008.001.08</MsgDefIdr>
<BizSvc>swift.cbprplus.02</BizSvc>
<CreDt>2024-07-03T20:43:32+10:00</CreDt>
</AppHdr>
<Document xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>M13782445</MsgId>
<CreDtTm>2024-07-03T20:43:32+10:00</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<SttlmInf>
<SttlmMtd>INDA</SttlmMtd>
</SttlmInf>
</GrpHdr>
<CdtTrfTxInf>
<PmtId>
<InstrId>M13782445</InstrId>
<EndToEndId>M13782445</EndToEndId>
<UETR>a3d0dc5e-1b14-4e21-b431-8cf64396a978</UETR>
</PmtId>
<IntrBkSttlmAmt Ccy = "CHF">50004166.67</IntrBkSttlmAmt>
<IntrBkSttlmDt>2024-04-12</IntrBkSttlmDt>
<ChrgBr>abc</ChrgBr>
<InstgAgt>
<FinInstnId>
<BICFI>CTBAAU2SFXD</BICFI>
</FinInstnId>
</InstgAgt>
<InstdAgt>
<FinInstnId>
<BICFI>TESTCSNSSFXXX</BICFI>
</FinInstnId>
</InstdAgt>
<IntrmyAgt1>
<FinInstnId>
<BICFI>TESTSWINT33</BICFI>
</FinInstnId>
</IntrmyAgt1>
<IntrmyAgt2>
<FinInstnId>
<BICFI>TESTSWINT22</BICFI>
</FinInstnId>
</IntrmyAgt2>
<Dbtr>
<Id>
<OrgId>
<AnyBIC>CTBAAU2SFXD</AnyBIC>
</OrgId>
</Id>
</Dbtr>
<DbtrAgt>
<FinInstnId>
<BICFI>TESTCSNSSFXXX</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtrAgt>
<FinInstnId>
<BICFI>TESTSWINT11</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Id>
<OrgId>
<AnyBIC>TESTSWTBEN1</AnyBIC>
</OrgId>
</Id>
</Cdtr>
<InstrForCdtrAgt>
<Cd>codcdtr1</Cd>
<InstrInf>intfcdtr1</InstrInf>
</InstrForCdtrAgt>
<InstrForNxtAgt>
<InstrInf>infnxt1</InstrInf>
</InstrForNxtAgt>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
</Body>
</DataPDU>
Ниже приведен мой целевой вывод xml:
<DataPDU xmlns = "http://www.tutorialspoint.com" xmlns:tp = "http://www.tutorialspoint.com" xmlns:head = "urn:iso:std:iso:20022:tech:xsd:head.001.001.04" xmlns:header = "urn:iso:std:iso:20022:tech:xsd:header.001.001.04" xmlns:pacs = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12">
<tp:Revision>2.0.10</tp:Revision>
<tp:Header>
<header:Message>
<header:SenderReference>112712406</header:SenderReference>
<header:MessageIdentifier>pacs.008.001.08</header:MessageIdentifier>
<header:Format>MX</header:Format>
<header:SubFormat>Input</header:SubFormat>
<header:Sender>
<header:DN>ou=xxx,o=ctbaau2s,o=swift</header:DN>
<header:FullName>
<header:X1>CTBAAU2SFXD</header:X1>
</header:FullName>
</header:Sender>
<header:Receiver>
<header:DN>ou=xxx,o=testcsns,o=swift</header:DN>
<header:FullName>
<header:X1>TESTCSNSSFX</header:X1>
</header:FullName>
</header:Receiver>
<header:InterfaceInfo>
<header:UserReference>M13782445</header:UserReference>
</header:InterfaceInfo>
<header:NetworkInfo>
<header:SWIFTNetNetworkInfo>
<header:RequestType>pacs.008.001.08</header:RequestType>
<header:RequestSubtype>swift.cbprplus.02</header:RequestSubtype>
</header:SWIFTNetNetworkInfo>
</header:NetworkInfo>
</header:Message>
</tp:Header>
</DataPDU>
Ниже мой XSLT:
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:main = "urn:swift:saa:xsd:saa.2.0" xmlns = "http://www.tutorialspoint.com" xmlns:tp = "http://www.tutorialspoint.com" xmlns:head = "urn:iso:std:iso:20022:tech:xsd:head.001.001.04" xmlns:header = "urn:iso:std:iso:20022:tech:xsd:header.001.001.04" version = "1.0">
<xsl:template match = "/">
<DataPDU>
<tp:Revision>
<xsl:value-of select = "/main:DataPDU/main:Header/main:Message/main:MessageIdentifier" />
</tp:Revision>
<tp:Header>
<!--
<xsl:apply-templates select = "/main:DataPDU/main:Header/main:Message" />
-->
<xsl:apply-templates />
</tp:Header>
</DataPDU>
</xsl:template>
<xsl:template match = "*[ancestor-or-self::main:Message]">
<xsl:element name = "header:{local-name()}">
<xsl:apply-templates select = "@*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match = "@*|node()">
<xsl:copy>
<xsl:apply-templates select = "@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Это по-прежнему дает неправильный вывод, как показано ниже. Провел много исследований, все еще пытаясь понять, как это сделать.
Неправильный вывод:
<?xml version = "1.0" encoding = "UTF-8"?>
<DataPDU xmlns = "http://www.tutorialspoint.com" xmlns:header = "urn:iso:std:iso:20022:tech:xsd:header.001.001.04" xmlns:head = "urn:iso:std:iso:20022:tech:xsd:head.001.001.04" xmlns:tp = "http://www.tutorialspoint.com" xmlns:main = "urn:swift:saa:xsd:saa.2.0">
<tp:Revision>pacs.008.001.08</tp:Revision>
<tp:Header>
<DataPDU xmlns = "urn:swift:saa:xsd:saa.2.0">
<Revision>2.0.10</Revision>
<Header>
<header:Message>
<header:SenderReference>112712406</header:SenderReference>
<header:MessageIdentifier>pacs.008.001.08</header:MessageIdentifier>
<header:Format>MX</header:Format>
<header:SubFormat>Input</header:SubFormat>
<header:Sender>
<header:DN>ou=xxx,o=ctbaau2s,o=swift</header:DN>
<header:FullName>
<header:X1>CTBAAU2SFXD</header:X1>
</header:FullName>
</header:Sender>
<header:Receiver>
<header:DN>ou=xxx,o=testcsns,o=swift</header:DN>
<header:FullName>
<header:X1>TESTCSNSSFXXX</header:X1>
</header:FullName>
</header:Receiver>
<header:InterfaceInfo>
<header:UserReference>M13782445</header:UserReference>
</header:InterfaceInfo>
<header:NetworkInfo>
<header:SWIFTNetNetworkInfo>
<header:RequestType>pacs.008.001.08</header:RequestType>
<header:RequestSubtype>swift.cbprplus.02</header:RequestSubtype>
</header:SWIFTNetNetworkInfo>
</header:NetworkInfo>
</header:Message>
</Header>
<Body>
<AppHdr xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<Fr xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<FIId xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">CTBAAU2SFXD</BICFI>
</FinInstnId>
</FIId>
</Fr>
<To xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<FIId xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">TESTCSNSSFXXX</BICFI>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">M13782445</BizMsgIdr>
<MsgDefIdr xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">pacs.008.001.08</MsgDefIdr>
<BizSvc xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">swift.cbprplus.02</BizSvc>
<CreDt xmlns = "urn:iso:std:iso:20022:tech:xsd:head.001.001.02">2024-07-03T20:43:32+10:00</CreDt>
</AppHdr>
<Document xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FIToFICstmrCdtTrf xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<GrpHdr xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<MsgId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">M13782445</MsgId>
<CreDtTm xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">2024-07-03T20:43:32+10:00</CreDtTm>
<NbOfTxs xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">1</NbOfTxs>
<SttlmInf xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<SttlmMtd xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">INDA</SttlmMtd>
</SttlmInf>
</GrpHdr>
<CdtTrfTxInf xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<PmtId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<InstrId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">M13782445</InstrId>
<EndToEndId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">M13782445</EndToEndId>
<UETR xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">a3d0dc5e-1b14-4e21-b431-8cf64396a978</UETR>
</PmtId>
<IntrBkSttlmAmt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08" Ccy = "CHF">50004166.67</IntrBkSttlmAmt>
<IntrBkSttlmDt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">2024-04-12</IntrBkSttlmDt>
<ChrgBr xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">abc</ChrgBr>
<InstgAgt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">CTBAAU2SFXD</BICFI>
</FinInstnId>
</InstgAgt>
<InstdAgt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">TESTCSNSSFXXX</BICFI>
</FinInstnId>
</InstdAgt>
<IntrmyAgt1 xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">TESTSWINT33</BICFI>
</FinInstnId>
</IntrmyAgt1>
<IntrmyAgt2 xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">TESTSWINT22</BICFI>
</FinInstnId>
</IntrmyAgt2>
<Dbtr xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<Id xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<OrgId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<AnyBIC xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">CTBAAU2SFXD</AnyBIC>
</OrgId>
</Id>
</Dbtr>
<DbtrAgt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">TESTCSNSSFXXX</BICFI>
</FinInstnId>
</DbtrAgt>
<CdtrAgt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<FinInstnId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<BICFI xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">TESTSWINT11</BICFI>
</FinInstnId>
</CdtrAgt>
<Cdtr xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<Id xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<OrgId xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<AnyBIC xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">TESTSWTBEN1</AnyBIC>
</OrgId>
</Id>
</Cdtr>
<InstrForCdtrAgt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<Cd xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">codcdtr1</Cd>
<InstrInf xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">intfcdtr1</InstrInf>
</InstrForCdtrAgt>
<InstrForNxtAgt xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
<InstrInf xmlns = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">infnxt1</InstrInf>
</InstrForNxtAgt>
</CdtTrfTxInf>
</FIToFICstmrCdtTrf>
</Document>
</Body>
</DataPDU>
</tp:Header>
</DataPDU>
Я думаю, что желаемый результат можно получить просто:
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:main = "urn:swift:saa:xsd:saa.2.0"
xmlns:tp = "http://www.tutorialspoint.com"
xmlns:header = "urn:iso:std:iso:20022:tech:xsd:header.001.001.04"
xmlns = "http://www.tutorialspoint.com"
exclude-result-prefixes = "main">
<xsl:output method = "xml" indent = "yes"/>
<xsl:strip-space elements = "*"/>
<xsl:template match = "/main:DataPDU">
<DataPDU>
<xsl:apply-templates select = "main:Revision | main:Header"/>
</DataPDU>
</xsl:template>
<xsl:template match = "main:Revision | main:Header">
<xsl:element name = "tp:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match = "main:*">
<xsl:element name = "header:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Я пропустил эти объявления пространства имен, потому что не вижу, чтобы они где-либо использовались:
xmlns:head = "urn:iso:std:iso:20022:tech:xsd:head.001.001.04"
xmlns:pacs = "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.12"
Но если вы хотите, вы можете добавить их в пространства имен, объявленные в стартовом теге xsl:stylesheet
, и они будут скопированы в выходные данные.
Вероятно, не хватает еще одного шаблона отключения, соответствующего желаемому результату: <xsl:template match = "main:Body"/>
@YitzhakKhabinsky Чем мой вывод отличается от желаемого (кроме двух избыточных пространств имен)?
Кажется, фрагмент Body не нужен
@YitzhakKhabinsky Боюсь, я понятия не имею, чего ты от меня хочешь. Вы запускали мой код с вводом ОП? Если да, то чем результат отличается от результата, указанного в вопросе? Если нет, то зачем вы тратите мое время на эти комментарии?
@y.arazim.. Спасибо большое. Это решило мою проблему.
Вот еще одно предложение, которое дает результат, который семантически, но не лексически совпадает с желаемым результатом.
Элементы в новом документе переименовываются для использования URI пространства имен http://www.tutorialspoint.com
, за исключением тех, которые были потомками элемента Message
, которые переименовываются для использования URI пространства имен urn:iso:std:iso:20022:tech:xsd:header.001.001.04
. В обоих случаях URI пространства имен используется как пространство имен по умолчанию (т. е. в именах элементов он используется без префикса). Между прочим, это дает наименьшую сериализацию нужных имен элементов.
Для отклонения этого элемента используется отдельный шаблон, соответствующий элементу Body
.
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:main = "urn:swift:saa:xsd:saa.2.0"
exclude-result-prefixes = "main">
<xsl:output method = "xml" indent = "yes"/>
<xsl:strip-space elements = "*"/>
<xsl:template match = "*[ancestor-or-self::main:Message]">
<xsl:element name = "{local-name()}" namespace = "urn:iso:std:iso:20022:tech:xsd:header.001.001.04">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match = "*">
<xsl:element name = "{local-name()}" namespace = "http://www.tutorialspoint.com">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match = "main:Body"/>
</xsl:stylesheet>
Результат:
<?xml version = "1.0" encoding = "UTF-8"?>
<DataPDU xmlns = "http://www.tutorialspoint.com">
<Revision>2.0.10</Revision>
<Header>
<Message xmlns = "urn:iso:std:iso:20022:tech:xsd:header.001.001.04">
<SenderReference>112712406</SenderReference>
<MessageIdentifier>pacs.008.001.08</MessageIdentifier>
<Format>MX</Format>
<SubFormat>Input</SubFormat>
<Sender>
<DN>ou=xxx,o=ctbaau2s,o=swift</DN>
<FullName>
<X1>CTBAAU2SFXD</X1>
</FullName>
</Sender>
<Receiver>
<DN>ou=xxx,o=testcsns,o=swift</DN>
<FullName>
<X1>TESTCSNSSFXXX</X1>
</FullName>
</Receiver>
<InterfaceInfo>
<UserReference>M13782445</UserReference>
</InterfaceInfo>
<NetworkInfo>
<SWIFTNetNetworkInfo>
<RequestType>pacs.008.001.08</RequestType>
<RequestSubtype>swift.cbprplus.02</RequestSubtype>
</SWIFTNetNetworkInfo>
</NetworkInfo>
</Message>
</Header>
</DataPDU>
Большое спасибо. Это решило мою проблему.
Есть ли причина, по которой вы хотите сделать
http://www.tutorialspoint.com
пространством имен по умолчанию для документа, а также привязать его к префиксуtp
?