📜 ⬆️ ⬇️

1C magic XDTO-packages on the example of integration with GIS utilities

There are so many articles on how to work with XSL / XSD from 1C, but they are all in style: take our XSD scheme (simple and udbonoy) or our web service and see how easy it is to export or import everything. What to do if we were given a pack of XSD-schemes with complex interrelationships and we cannot change them, but do we need to work and maintain the relevance of the schemes?

At once I will say that encryption / signature issues in accordance with GOST when working with GIS utilities beyond the scope of this article and in the Habré have already been covered. Although no signatures can not complete requests.

image
Let's start with a simple one - download the format package for integration interaction with GIS utilities , import all xsd schemes from the integration package, adjust the order and rename everything as convenient for us. As a result, we get as shown in the picture:

Now let's get down to magic. Let's try to request data from the directory of organizations on ORGN. This is the organization-registry-common subsystem of the exportOrgRegist.

The hcs-organizations-registry-common-service.wsdl states:
')
Specification from hcs-organizations-registry-common-service.wsdl
... <wsdl:message name="exportOrgRegistryRequest"> <wsdl:part name="exportOrgRegistryRequest" element="ro:exportOrgRegistryRequest"/> </wsdl:message> <wsdl:message name="exportOrgRegistryResult"> <wsdl:part name="exportOrgRegistryResult" element="ro:exportOrgRegistryResult"/> </wsdl:message> ... <wsdl:message name="ISRequestHeader"> <wsdl:part name="Header" element="ISRequestHeader"/> </wsdl:message> ... <wsdl:operation name="exportOrgRegistry"> <wsdl:documentation>   </wsdl:documentation> <wsdl:input message="tns:exportOrgRegistryRequest"/> <wsdl:output message="tns:exportOrgRegistryResult"/> <wsdl:fault name="InvalidRequest" message="tns:Fault"/> </wsdl:operation> ... <wsdl:operation name="exportOrgRegistry"> <soap:operation soapAction="urn:exportOrgRegistry"/> <wsdl:input> <soap:body use="literal"/> <soap:header message="tns:ISRequestHeader" part="Header" use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> <soap:header message="tns:ResultHeader" part="Header" use="literal"/> </wsdl:output> <wsdl:fault name="InvalidRequest"> <soap:fault name="InvalidRequest" use="literal"/> </wsdl:fault> </wsdl:operation> 


It is necessary to collect the SOAP package from the ISRequestHeader header, the body of exportOrgRegistryRequest. Let's look at them in xsd integration specifications schemes.
hcs-base.xsd
 ... <xs:element name="ISRequestHeader" type="tns:HeaderType"> <xs:annotation> <xs:documentation> </xs:documentation> </xs:annotation> </xs:element> ... <xs:complexType name="HeaderType"> <xs:annotation> <xs:documentation>  </xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="Date" type="xs:dateTime"> <xs:annotation> <xs:documentation>  </xs:documentation> </xs:annotation> </xs:element> <xs:element name="MessageGUID" type="tns:GUIDType"> <xs:annotation> <xs:documentation> </xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> ... <xs:simpleType name="GUIDType"> <xs:annotation> <xs:documentation>GUID-.</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:pattern value="([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}"/> </xs:restriction> </xs:simpleType> ... 

hcs-organizations-base.xsd
 ... <xs:element name="OGRN" type="tns:OGRNType"> <xs:annotation> <xs:documentation></xs:documentation> </xs:annotation> </xs:element> <xs:simpleType name="OGRNType"> <xs:restriction base="xs:string"> <xs:length value="13"/> </xs:restriction> </xs:simpleType> ... 

hcs-organizations-registry-common-types.xsd
 ... <!--   --> <xs:element name="exportOrgRegistryRequest"> <xs:annotation> <xs:documentation>    </xs:documentation> </xs:annotation> <xs:complexType> <xs:complexContent> <xs:extension base="base:BaseType"> <xs:sequence> <xs:element name="SearchCriteria" maxOccurs="100"> <xs:annotation> <xs:documentation>  .</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:choice> <xs:choice> <xs:annotation> <xs:documentation>  .</xs:documentation> </xs:annotation> <xs:element ref="organizations-base:OGRNIP"/> <xs:sequence> <xs:element ref="organizations-base:OGRN"/> <xs:element ref="organizations-base:KPP" minOccurs="0"/> </xs:sequence> <xs:element ref="organizations-base:NZA"/> </xs:choice> <xs:element ref="organizations-registry-base:orgVersionGUID"/> <xs:element ref="organizations-registry-base:orgRootEntityGUID"/> </xs:choice> <xs:element name="isRegistered" type="xs:boolean" fixed="true" minOccurs="0"> <xs:annotation> <xs:documentation>  ,   </xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="lastEditingDateFrom" type="xs:date" minOccurs="0"> <xs:annotation> <xs:documentation>   ()</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> <xs:attribute ref="base:version" use="required" fixed="10.0.2.1"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="exportOrgRegistryResult"> <xs:complexType> <xs:complexContent> <xs:extension base="base:BaseType"> <xs:choice> <xs:element ref="base:ErrorMessage"/> <xs:element name="OrgData" type="tns:exportOrgRegistryResultType" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation> .</xs:documentation> </xs:annotation> </xs:element> </xs:choice> <xs:attribute ref="base:version" use="required" fixed="10.0.2.1"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:complexType name="exportOrgRegistryResultType"> <xs:sequence> <xs:element ref="organizations-registry-base:orgRootEntityGUID"/> <xs:element name="OrgVersion"> <xs:annotation> <xs:documentation>    </xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element ref="organizations-registry-base:orgVersionGUID"/> <xs:element name="lastEditingDate" type="xs:date"> <xs:annotation> <xs:documentation>  </xs:documentation> </xs:annotation> </xs:element> <xs:element name="IsActual" type="xs:boolean"> <xs:annotation> <xs:documentation>  </xs:documentation> </xs:annotation> </xs:element> <xs:choice> <xs:element name="Legal" type="organizations-registry-base:LegalType"> <xs:annotation> <xs:documentation> </xs:documentation> </xs:annotation> </xs:element> <xs:element name="Subsidiary"> <xs:annotation> <xs:documentation> </xs:documentation> </xs:annotation> <xs:complexType> <xs:complexContent> <xs:extension base="organizations-registry-base:SubsidiaryType"> <xs:sequence> <xs:element name="StatusVersion"> <xs:annotation> <xs:documentation>  </xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"/> </xs:simpleType> </xs:element> <xs:element name="ParentOrg"> <xs:annotation> <xs:documentation>   </xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element ref="organizations-registry-base:RegOrgVersion"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="Entrp" type="organizations-registry-base:EntpsType"> <xs:annotation> <xs:documentation> </xs:documentation> </xs:annotation> </xs:element> <xs:element name="ForeignBranch" type="organizations-registry-base:ForeignBranchType"> <xs:annotation> <xs:documentation> (     )</xs:documentation> </xs:annotation> </xs:element> </xs:choice> <xs:element name="registryOrganizationStatus" minOccurs="0"> <xs:annotation> <xs:documentation>: (P)UBLISHED -        </xs:documentation> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="P"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element ref="base:orgPPAGUID" minOccurs="0"/> <xs:element name="organizationRoles" type="nsi-base:nsiRef" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>  ( â„–20)</xs:documentation> </xs:annotation> </xs:element> <xs:element name="isRegistered" type="xs:boolean" fixed="true" minOccurs="0"> <xs:annotation> <xs:documentation>   </xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> ... 

Well, let's start, we will open the XDTO packages we need. It turns out that the required entities are not types, but properties, how to work with this in the XDTO documentation in the articles I found is not described, so we will use the lessons of magic:


image

Let's start with the body exportOrgRegistryRequest.

 &  () //   OrgRegCom = XDTO..("http://dom.gosuslugi.ru/schema/integration/organizations-registry-common/"); OrgBase = XDTO..("http://dom.gosuslugi.ru/schema/integration/organizations-base/"); //:     ,      : XDTO = OrgRegCom..("exportOrgRegistryRequest"); //      XDTO = XDTO.(XDTO.); //       XDTO.Id = "signed-data-container"; // ,  XDTO    fixed XDTO.version = "10.0.2.1"; //  //:    ,    SearchCriteria = XDTO.(XDTO.SearchCriteria..); //      OGRN = XDTO.(OrgBase..("OGRN")., ()); SearchCriteria.OGRN = OGRN; XDTO.SearchCriteria.(SearchCriteria); //   =  ("XDTO,XDTO,", XDTO, XDTO); //  ,       XDTOResult = OrgRegCom..("exportOrgRegistryResult");  XML( , , XDTOResult );  

Let's write a function to collect the XML request:

 &  XML(Guid, XDTO, XDTO) Base = XDTO..("http://dom.gosuslugi.ru/schema/integration/base/"); SOAP = "http://schemas.xmlsoap.org/soap/envelope/"; //XML  XML =  XML; XML =  XML("UTF-8"); XML.(XML); XML.XML(); XML.("Envelope", SOAP); XML.("soap", SOAP); XML.("xsi", "http://www.w3.org/2001/XMLSchema-instance"); XML.("xs", "http://www.w3.org/2001/XMLSchema"); XML.("base", "http://dom.gosuslugi.ru/schema/integration/base/"); XML.("organizations-registry-base", "http://dom.gosuslugi.ru/schema/integration/organizations-registry-base/"); XML.("ns", "http://www.w3.org/2000/09/xmldsig#"); XML.("ro", "http://dom.gosuslugi.ru/schema/integration/organizations-registry-common/"); // ISRequestHeader XML.("Header", SOAP); //    XDTO = Base..("ISRequestHeader");  = XDTO.(XDTO.); .Date = (); .MessageGUID = XDTO.(XDTO.("http://dom.gosuslugi.ru/schema/integration/base/", "GUIDType"), (Guid)); XDTO.XML(XML, , XDTO.); XML.(); //     exportOrgRegistryRequest XML.("Body", SOAP); XDTO.XML(XML, XDTO.XDTO, XDTO.XDTO., XDTO.XDTO.URI); XML.(); XML.(); //    XML =  (); XML.("XMLT", XML.()); XML.("XDTO", XDTO);  XML;  

As a result, we get the request:

XML request exportOrgRegistryRequest
 <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:base="http://dom.gosuslugi.ru/schema/integration/base/" xmlns:hm="http://dom.gosuslugi.ru/schema/integration/house-management/" xmlns:ns="http://www.w3.org/2000/09/xmldsig#" xmlns:nsi-base="http://dom.gosuslugi.ru/schema/integration/nsi-base/" xmlns:nsi-common="http://dom.gosuslugi.ru/schema/integration/nsi-common/" xmlns:organizations-registry-base="http://dom.gosuslugi.ru/schema/integration/organizations-registry-base/" xmlns:ro="http://dom.gosuslugi.ru/schema/integration/organizations-registry-common/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://dom.gosuslugi.ru/schema/integration/house-management-service/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <base:ISRequestHeader> <base:Date>2016-10-29T20:06:35</base:Date> <base:MessageGUID>8120c453-d4ee-4918-84f8-276257bb2c84</base:MessageGUID> </base:ISRequestHeader> </soap:Header> <soap:Body> <ro:exportOrgRegistryRequest Id="signed-data-container" base:version="10.0.2.1"> <!--       ,    --> <ro:SearchCriteria> <OGRN xmlns="http://dom.gosuslugi.ru/schema/integration/organizations-base/">1027700132195</OGRN> </ro:SearchCriteria> </ro:exportOrgRegistryRequest> </soap:Body> </soap:Envelope> 


Send a request:

 &  () //    XML = ("1027700132195"); //     //     //  Post    XML = XML(XML);  XML. < 299  //  XDTO = (XML., XML.XDTO) ;  

Answer from GIS utilities servers (SIT-1):

XML response exportOrgRegistryResult
 <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:ns10="http://dom.gosuslugi.ru/schema/integration/organizations-base/" xmlns:ns11="http://dom.gosuslugi.ru/schema/integration/payments-base/" xmlns:ns12="http://dom.gosuslugi.ru/schema/integration/bills-base/" xmlns:ns13="http://dom.gosuslugi.ru/schema/integration/organizations-registry-common/" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#" xmlns:ns4="http://dom.gosuslugi.ru/schema/integration/base/" xmlns:ns5="http://dom.gosuslugi.ru/schema/integration/account-base/" xmlns:ns6="http://dom.gosuslugi.ru/schema/integration/nsi-base/" xmlns:ns7="http://dom.gosuslugi.ru/schema/integration/individual-registry-base/" xmlns:ns8="http://dom.gosuslugi.ru/schema/integration/metering-device-base/" xmlns:ns9="http://dom.gosuslugi.ru/schema/integration/organizations-registry-base/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <ns4:ResultHeader> <ns4:Date>2016-10-29T20:06:37.185+03:00</ns4:Date> <ns4:MessageGUID>8120c453-d4ee-4918-84f8-276257bb2c84</ns4:MessageGUID> </ns4:ResultHeader> </soap:Header> <soap:Body> <ns13:exportOrgRegistryResult Id="signed-data-container" ns4:version="10.0.2.1"> <!--       --> <ns13:OrgData> <ns9:orgRootEntityGUID>50a8619b-2d27-4f20-8233-eab1ccf9dffe</ns9:orgRootEntityGUID> <ns13:OrgVersion> <ns9:orgVersionGUID>50a8619b-2d27-4f20-8233-eab1ccf9dffe</ns9:orgVersionGUID> <ns13:lastEditingDate>2015-08-10+03:00</ns13:lastEditingDate> <ns13:IsActual>true</ns13:IsActual> <ns13:Legal> <ns9:ShortName> « »</ns9:ShortName> <ns9:FullName> « »</ns9:FullName> <ns10:OGRN>1027700132195</ns10:OGRN> <ns9:StateRegistrationDate>2015-08-10+03:00</ns9:StateRegistrationDate> <ns10:INN>7707083893</ns10:INN> <ns10:KPP>775001001</ns10:KPP> <ns10:OKOPF>12247</ns10:OKOPF> <ns9:Address>. , . , . 19</ns9:Address> <ns9:FIASHouseGuid>93409d8c-d8d4-4491-838f-f9aa1678b5e6</ns9:FIASHouseGuid> </ns13:Legal> <ns13:registryOrganizationStatus>P</ns13:registryOrganizationStatus> </ns13:OrgVersion> <ns4:orgPPAGUID>2c57ed5e-583a-4471-839e-776250bdde50</ns4:orgPPAGUID> <ns13:organizationRoles> <ns6:Code>1</ns6:Code> <ns6:GUID>9875cc2e-73f9-41d6-bceb-47b48ed23395</ns6:GUID> <ns6:Name> </ns6:Name> </ns13:organizationRoles> <ns13:isRegistered>true</ns13:isRegistered> </ns13:OrgData> </ns13:exportOrgRegistryResult> </soap:Body> </soap:Envelope> 


As we can see, the answer cannot be directly deserialized, because there is no such type in the proposed xsd schemes. We need to somehow skip part of the tags and process only the response area. I also did not find information on this topic, but by trial and error we come to a piece of magic:

 &  (, XDTO) //   =  XML; .(, , , "UTF-8"); //    ,       .()   . = XDTO.XDTO.  //..        .  XDTO = XDTO.XML(, XDTO.XDTO.); ; ;  XDTO;  

As a result, you can work with very complex xsd schemes through standard platform tools. In general, 1C controls typing and filling, it is too redundant, especially when the base type of another package is used inside the package property, but in any case, the type must be localized due to a different URI space. It is convenient to work with deserialized data, since the platform takes over all the work there. But checks occur at runtime, and when writing code, the 1C platform does not provide any prompts and traverses to use third-party utilities, and even when executed, most of the elements are in the “Undefined” state and even the type or its property can be seen only in the specification.

Source: https://habr.com/ru/post/313910/


All Articles