Commit 43bda1f4 by chengzhuoshen

增加mx报文的schema校验,并提交appHdr.xsd

parent 99d4aada
......@@ -8,15 +8,28 @@ import com.brilliance.swift.swiftdto2mx.SwiftDto2MxCreatorManager;
import com.brilliance.swift.util.StringUtil;
import com.brilliance.swift.util.XmlUtil;
import com.brilliance.swift.vo.SwiftDto;
import com.prowidesoftware.swift.model.MxId;
import com.prowidesoftware.swift.model.mx.AbstractMX;
import com.prowidesoftware.swift.model.mx.NamespaceReader;
import org.apache.commons.io.FileUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.xml.sax.SAXException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SwiftTransfer {
......@@ -110,4 +123,78 @@ public class SwiftTransfer {
return new Mx2MapCreatorManager().mx2Map(xmlStr);
}
/**
* 根据xml的内容获取对应的xsd文件并校验
* 失败则抛出异常
* @param xml
* @return
*/
public static boolean validateMx(String xml) {
//1.获取AppHdr报文内容,根据@xmlns获取版本对应的xsd文件
String regex = "(\\<AppHdr[\\w\\W]*\\<\\/AppHdr\\>)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(xml);
String appHdrXml = "";
if (m.find()) {
appHdrXml = m.group(1);
}
String appHdrXsdName = null;
Optional<String> namespace = NamespaceReader.findAppHdrNamespace(xml);
if (namespace.isPresent()) {
MxId appHdrMxId = new MxId(namespace.get());
appHdrXsdName = appHdrMxId.getBusinessProcess().name()
+ appHdrMxId.getFunctionality()
+ appHdrMxId.getVariant()
+ appHdrMxId.getVersion();
}
if (StringUtil.isNotEmpty(appHdrXsdName) && StringUtil.isNotEmpty(appHdrXml)) {
schemaValidate(appHdrXsdName, appHdrXml);
}
//2.获取Document报文内容,根据@xmlns获取版本对应的xsd文件
regex = "(\\<Document[\\w\\W]*\\<\\/Document\\>)";
p = Pattern.compile(regex);
m = p.matcher(xml);
String documentXml = "";
if (m.find()) {
documentXml = m.group(1);
}
String documentXsdName = "";
namespace = NamespaceReader.findDocumentNamespace(xml);
if (namespace.isPresent()) {
MxId documentMxId = new MxId(namespace.get());
documentXsdName = documentMxId.getBusinessProcess().name()
+ documentMxId.getFunctionality()
+ documentMxId.getVariant()
+ documentMxId.getVersion();
}
if (StringUtil.isNotEmpty(documentXsdName) && StringUtil.isNotEmpty(documentXml)) {
schemaValidate(documentXsdName, documentXml);
}
return true;
}
public static void schemaValidate(String xsdName, String xml) {
try {
//建立schema工厂
SchemaFactory schemaFactory = SchemaFactory
.newInstance("http://www.w3.org/2001/XMLSchema");
URL url = SwiftTransfer.class.getResource("/xsd/"+xsdName+".xsd");
//利用schema工厂,接收验证文档文件对象生成Schema对象
Schema schema = schemaFactory.newSchema(url);
// 开始验证
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))));
} catch (SAXException e) {
throw new SwiftException("Error", e.getMessage());
} catch (IOException e) {
throw new SwiftException("Error", e.getMessage());
}
}
public static void main(String[] args) throws IOException {
File file = new File(System.getProperty("user.dir")+"\\swiftCore\\src\\main\\resources\\swiftXml\\MxPacs00800108.xml");
String xmlStr = FileUtils.readFileToString(file);
validateMx(xmlStr);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Legal Notices
SWIFT SCRL@2016. All rights reserved.
This schema is a component of MyStandards, the SWIFT collaborative Web application used to manage
standards definitions and industry usage.
This is a licensed product, which may only be used and distributed in accordance with MyStandards License
Terms as specified in MyStandards Service Description and the related Terms of Use.
Unless otherwise agreed in writing with SWIFT SCRL, the user has no right to:
- authorise external end users to use this component for other purposes than their internal use.
- remove, alter, cover, obfuscate or cancel from view any copyright or other proprietary rights notices appearing in this physical medium.
- re-sell or authorise another party e.g. software and service providers, to re-sell this component.
This component is provided 'AS IS'. SWIFT does not give and excludes any express or implied warranties
with respect to this component such as but not limited to any guarantee as to its quality, supply or availability.
Any and all rights, including title, ownership rights, copyright, trademark, patents, and any other intellectual
property rights of whatever nature in this component will remain the exclusive property of SWIFT or its
licensors.
Trademarks
SWIFT is the trade name of S.W.I.F.T. SCRL.
The following are registered trademarks of SWIFT: the SWIFT logo, SWIFT, SWIFTNet, SWIFTReady, Accord, Sibos, 3SKey, Innotribe, the Standards Forum logo, MyStandards, and SWIFT Institute.
Other product, service, or company names in this publication are trade names, trademarks, or registered trademarks of their respective owners.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Group: Payments Canada
Collection: RTR_FINAL_V1.2_CoreMessages_SR2019
Usage Guideline: RTR_BusinessApplicationHeaderV02_head.001.001.02
Base Message: head.001.001.02
Date of publication: 11 April 2022
URL: https://www2.swift.com/mystandards/#/mp/mx/_L_b1kJ8bEeyX2-3WgfEAkg/_L_b1kZ8bEeyX2-3WgfEAkg
Description: This document outlines the specifications for the RTR ISO 20022 Business Application Header message. Prior to reading this RTR ISO 20022 Message Specification, it is highly recommended to read the RTR ISO 20022 Message Specification Companion Document that is published alongside it since the Companion provides high-level context and an overview of the message portfolio and content.
RTR Usage:
Payments Canada will use the Business Application Header for all messages in the RTR ISO 20022 portfolio.
The Business Layer deals with Business Messages. The behaviour of the Business Messages is fully described by the Business Transaction and the structure of the Business Messages is fully described by the Message Definitions and related Message Rules, Rules and Market Practices. All of which are registered in the ISO 20022 Repository.
A single new Business Message (with its accompagnying business application header) is created - by the sending MessagingEndpoint - for each business event; that is each interaction in a Business Transaction. A Business Message adheres to the following principles:
" A Business Message (and its business application header) must not contain information about the Message Transport System or the mechanics or mechanism of message sending, transportation, or receipt.
" A Business Message must be comprehensible outside of the context of the Transport Message. That is the Business Message must not require knowledge of the Transport Message to be understood.
" A Business Message may contain headers, footers, and envelopes that are meaningful for the business. When present, they are treated as any other message content, which means that they are considered part of the Message Definition of the Business Message and as such will be part of the ISO 20022 Repository.
" A Business Message refers to Business Actors by their Name. Each instance of a Business Actor has one Name. The Business Actor must not be referred to in the Transport Layer.
Specific usage of this BusinessMessageHeader may be defined by the relevant SEG.
Generated by the MyStandards web platform [https://www.swift.com/mystandards] on 2022-05-25T23:24:24+00:00
-->
<xs:schema xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.02" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:iso:std:iso:20022:tech:xsd:head.001.001.02">
<xs:element name="AppHdr" type="BusinessApplicationHeaderV02"/>
<xs:complexType name="BusinessApplicationHeaderV02">
<xs:sequence>
<xs:element name="Fr" type="Party44Choice"/>
<xs:element name="To" type="Party44Choice"/>
<xs:element name="BizMsgIdr" type="Max35Text"/>
<xs:element name="MsgDefIdr" type="Max35Text"/>
<xs:element name="BizSvc" type="Max35Text"/>
<xs:element name="CreDt" type="ISODateTime"/>
<xs:element maxOccurs="1" minOccurs="0" name="Prty" type="Priority2Code"/>
<xs:element maxOccurs="1" minOccurs="0" name="CpyDplct" type="CopyDuplicate1Code"/>
<xs:element maxOccurs="1" minOccurs="0" name="PssblDplct" type="YesNoIndicator"/>
<xs:element maxOccurs="1" minOccurs="0" name="Rltd" type="BusinessApplicationHeader5"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Party44Choice">
<xs:choice>
<xs:element name="FIId" type="BranchAndFinancialInstitutionIdentification6"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="BranchAndFinancialInstitutionIdentification6">
<xs:sequence>
<xs:element name="FinInstnId" type="FinancialInstitutionIdentification18"/>
<xs:element maxOccurs="1" minOccurs="0" name="BrnchId" type="BranchData3"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BusinessApplicationHeader5">
<xs:sequence>
<xs:element name="Fr" type="Party44Choice"/>
<xs:element name="To" type="Party44Choice"/>
<xs:element name="BizMsgIdr" type="Max35Text"/>
<xs:element name="MsgDefIdr" type="Max35Text"/>
<xs:element name="CreDt" type="ISODateTime"/>
<xs:element maxOccurs="1" minOccurs="0" name="Prty" type="Priority2Code"/>
<xs:element maxOccurs="1" minOccurs="0" name="CpyDplct" type="CopyDuplicate1Code"/>
<xs:element maxOccurs="1" minOccurs="0" name="PssblDplct" type="YesNoIndicator"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="FinancialInstitutionIdentification18">
<xs:sequence>
<xs:element name="BICFI" type="BICFIDec2014Identifier"/>
<xs:element maxOccurs="1" minOccurs="0" name="ClrSysMmbId" type="ClearingSystemMemberIdentification2"/>
<xs:element maxOccurs="1" minOccurs="0" name="LEI" type="LEIIdentifier"/>
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress24"/>
<xs:element maxOccurs="1" minOccurs="0" name="Othr" type="GenericFinancialIdentification1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BranchData3">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="Id" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="LEI" type="LEIIdentifier"/>
<xs:element maxOccurs="1" minOccurs="0" name="Nm" type="Max140Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="PstlAdr" type="PostalAddress24"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ClearingSystemMemberIdentification2">
<xs:sequence>
<xs:element name="ClrSysId" type="ClearingSystemIdentification2Choice"/>
<xs:element name="MmbId" type="Max35Text"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="Priority2Code">
<xs:restriction base="xs:string">
<xs:enumeration value="HIGH"/>
<xs:enumeration value="NORM"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CopyDuplicate1Code">
<xs:restriction base="xs:string">
<xs:enumeration value="COPY"/>
<xs:enumeration value="CODU"/>
<xs:enumeration value="DUPL"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ISODateTime">
<xs:restriction base="xs:dateTime">
<xs:pattern value=".*(\+|-)((0[0-9])|(1[0-3])):[0-5][0-9]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="BICFIDec2014Identifier">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LEIIdentifier">
<xs:restriction base="xs:string">
<xs:pattern value=" [A-Z0-9]{18,18}[0-9]{2,2}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Max16Text">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="16"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Max35Text">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="35"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Max70Text">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="70"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Max140Text">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="140"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ClearingSystemIdentification2Choice">
<xs:choice>
<xs:element name="Cd" type="ExternalClearingSystemIdentification1Code"/>
<xs:element name="Prtry" type="Max35Text"/>
</xs:choice>
</xs:complexType>
<xs:simpleType name="ExternalClearingSystemIdentification1Code">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="PostalAddress24">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="AdrTp" type="AddressType3Choice"/>
<xs:element maxOccurs="1" minOccurs="0" name="Dept" type="Max70Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="SubDept" type="Max70Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="StrtNm" type="Max70Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="BldgNb" type="Max16Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="BldgNm" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="Flr" type="Max70Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="PstBx" type="Max16Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="Room" type="Max70Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="PstCd" type="Max16Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="TwnNm" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="TwnLctnNm" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="DstrctNm" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="CtrySubDvsn" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="Ctry" type="CountryCode"/>
<xs:element maxOccurs="7" minOccurs="0" name="AdrLine" type="Max70Text"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddressType3Choice">
<xs:choice>
<xs:element name="Cd" type="AddressType2Code"/>
<xs:element name="Prtry" type="GenericIdentification30"/>
</xs:choice>
</xs:complexType>
<xs:simpleType name="AddressType2Code">
<xs:restriction base="xs:string">
<xs:enumeration value="ADDR"/>
<xs:enumeration value="PBOX"/>
<xs:enumeration value="HOME"/>
<xs:enumeration value="BIZZ"/>
<xs:enumeration value="MLTO"/>
<xs:enumeration value="DLVY"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="GenericIdentification30">
<xs:sequence>
<xs:element name="Id" type="Exact4AlphaNumericText"/>
<xs:element name="Issr" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="Max35Text"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="Exact4AlphaNumericText">
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9]{4}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CountryCode">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2,2}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AnyBICDec2014Identifier">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]{4,4}[A-Z]{2,2}[A-Z0-9]{2,2}([A-Z0-9]{3,3}){0,1}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="GenericFinancialIdentification1">
<xs:sequence>
<xs:element name="Id" type="Max35Text"/>
<xs:element maxOccurs="1" minOccurs="0" name="SchmeNm" type="FinancialIdentificationSchemeName1Choice"/>
<xs:element maxOccurs="1" minOccurs="0" name="Issr" type="Max35Text"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="FinancialIdentificationSchemeName1Choice">
<xs:choice>
<xs:element name="Cd" type="ExternalFinancialInstitutionIdentification1Code"/>
<xs:element name="Prtry" type="Max35Text"/>
</xs:choice>
</xs:complexType>
<xs:simpleType name="ExternalFinancialInstitutionIdentification1Code">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="YesNoIndicator">
<xs:restriction base="xs:boolean"/>
</xs:simpleType>
</xs:schema>
package com.brilliance.mx2mtmap.mt103;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.prowidesoftware.swift.model.mx.AbstractMX;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class Test {
public static void main(String[] args) throws IOException {
File file = new File(System.getProperty("user.dir")+"\\swiftCore\\src\\main\\resources\\swiftXml\\MxPacs00800109.xml");
File file = new File(System.getProperty("user.dir")+"\\swiftCore\\src\\main\\resources\\swiftXml\\MxPacs00800108.xml");
String xmlStr = FileUtils.readFileToString(file);
//String xmlStr = FileUtils.readFileToString(new File(System.getProperty("user.dir")+"\\swiftCore\\src\\main\\resources\\swiftXml\\MxCamt05400108_CREDIT.xml"));
//Map<String, Object> extraMap = new HashMap<>();
......@@ -33,27 +30,7 @@ public class Test {
AbstractMX abstractMX = AbstractMX.parse(xmlStr);
String gsonStr = abstractMX.toJson();
System.out.println(gsonStr);
AbstractMX abstractMX1 = AbstractMX.fromJson(gsonStr);
System.out.println(abstractMX1.message());
Map<String, Object> mxGsonMaps = JSON.parseObject(gsonStr);
//String swiftGsonStr = new JSONObject(mxGsonMaps).toJSONString();
//AbstractMX abstractMX1 = AbstractMX.fromJson(swiftGsonStr);
// System.out.println(abstractMX1.toString());
Map<String, Object> maps = (Map<String, Object>)mxGsonMaps.get("fiToFICstmrCdtTrf");
JSONArray jsonArrays = (JSONArray)maps.get("cdtTrfTxInf");
int size = jsonArrays.size();
for (int i=0; i<size; i++) {
Map<String, Object> tmpMaps = (Map<String, Object>)jsonArrays.get(i);
Map<String, Object> maps1 = (Map<String, Object>)tmpMaps.get("cdtr");
maps1 = (Map<String, Object>)maps1.get("pstlAdr");
JSONArray objs = (JSONArray)maps1.get("adrLine");
int objSize = objs.size();
for (int j=0; j<objSize; j++) {
System.out.println(objs.get(j).getClass());
}
}
//System.out.println(mxGsonMaps);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment