XDTO XMLRead just reads AnyType Or String

1C:Enterprise platform integration capabilities and techniques

#1
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

Well, once a year we think that XDTO is a great mechanism for synchronization. Every time we stuck with some problems.

We are tying to create some XML objects which are configuration independent. We know about XDTOSerialization mechanism, we use it, but we are not very happy with it so we decided to try abstract XDTO objects.

To create initial schema we exported a smaller configuration scheme and the imported it back as a XDTOpackage with the following namespace: "http://abaco.com.ec/exchange/bodegamovil". So it not directly related to configuration scheme and has another URI.

Then we export some objects. I will show only the most important parts

Code
Schema = XDTOFactory.ExportXMLSchema("http://abaco.com.ec/exchange/bodegamovil");
Factory = New XDTOFactory(Schema);

// For object types we directly create XDTO type and then Object 
XDTOType = XDTOFactory.Type("http://abaco.com.ec/exchange/bodegamovil", TypeString);
XDTOObj = XDTOFactory.Create(XDTOType);

// For references we directly assign the required type
XDTOType = XDTOFactory.Type("http://abaco.com.ec/exchange/bodegamovil", TypeString);
XDTOObj = XDTOFactory.Create(XDTOType, String(Value.UUID()));


.. and it seems to work

Code
<?xml version="1.0"?>

-<v8msg:Message xmlns:v8msg="http://v8.1c.ru/messages">


-<v8msg:Header>

<v8msg:ExchangePlan>BodegaMovil</v8msg:ExchangePlan>

<v8msg:To>BLL</v8msg:To>

<v8msg:From>BC</v8msg:From>

<v8msg:MessageNo>21</v8msg:MessageNo>

<v8msg:ReceivedNo>0</v8msg:ReceivedNo>

</v8msg:Header>


-<v8msg:Body>


-<DocumentObject.IngresoDeBienes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://abaco.com.ec/exchange/bodegamovil">

<Ref xsi:type="DocumentRef.IngresoDeBienes">4b0ee919-66a3-11e6-ab27-5ce0c537ecf8</Ref>

<DeletionMark>false</DeletionMark>

<Date>2016-08-20T01:57:01</Date>

<Number>000000002 </Number>

<Posted>true</Posted>

<Contraparte xsi:type="CatalogRef.Contrapartes">00000000-0000-0000-0000-000000000000</Contraparte>


-<Bienes xsi:type="DocumentTabularSectionRow.IngresoDeBienes.Bienes">

<Nomenclatura xsi:type="CatalogRef.Nomenclatura">ae1b9523-6063-11e6-9f5d-5ce0c537ecf8</Nomenclatura>

<Cantidad>1</Cantidad>

</Bienes>

</DocumentObject.IngresoDeBienes>

</v8msg:Body>

</v8msg:Message>



Then we are trying to read this XML and convert to XDTO again. So the same XDTO package is imported to another configuration.

Code
XDTOSchema = XDTOFactory.ExportXMLSchema("http://abaco.com.ec/exchange/bodegamovil");
Factory = New XDTOFactory(XDTOSchema);


If I just read from XML without explicitly defining the XDTO type I'll get AnyType

Code
ExchObj = Factory.ReadXML(XMLReader);


Quote
ExchObj XDTODataObject XDTODataObject
Bienes XDTODataObject XDTODataObject
Contraparte "00000000-0000-0000-0000-000000000000" String
Date "2016-08-20T01:57:01" String
DeletionMark "false" String
Number "000000002 " String
Posted "true" String
Ref "4b0ee919-66a3-11e6-ab27-5ce0c537ecf8" String

If I define explicitly XDTO type I will get DocumentObject.IngresoDeBienes and correct primitive types...

Code
ExchObj = Factory.ReadXML(XMLReader, Factory.Type("http://abaco.com.ec/exchange/bodegamovil","DocumentObject.IngresoDeBienes"));


Quote
ExchObj XDTODataObject XDTODataObject
Bienes XDTOList XDTOList
Contraparte "00000000-0000-0000-0000-000000000000" String
Date 8/20/2016 1:57:01 AM Date
DeletionMark False Boolean
Number "000000002 " String
Posted True Boolean
Ref "4b0ee919-66a3-11e6-ab27-5ce0c537ecf8" String

..but I still do not get correct types for References. They are just represented as strings.

And I do not want to explicitly define types because as you can see it is changes notification messages, so they could contain objects of any type.

p.s. I have attached schema and xml example so you can test it.

Edited: Alexey Gerasimov - Aug 22, 2016 11:07 PM
 
#2
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

Seems like .xsd are not permitted. So I rared them

 
#3
People who like this:0Yes/0No
Timofey Bugaevsky
Guest

Joined:
Company:

Hello, Alexey!

Than you for the detailed description.

Would you please tell which version of 1C:Enterprise platform do you use?

And it would be very helpful if you could create a sample configuration where I could reproduce this issue.

 
#4
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

8.3.8.1933

I have sent you database dump with example file to test.

 
#5
People who like this:0Yes/0No
Timofey Bugaevsky
Guest

Joined:
Company:

Thank you, Alexey.

The second parameter for ReadXML is what you needed, it was the correct guess:

Code
 IngresoDeBienesType = XDTOFactory.Type("http://abaco.com.ec/exchange/bodegamovil", "DocumentObject.IngresoDeBienes");
...
   ExchObj = Factory.ReadXML(XMLReader, IngresoDeBienesType);

Here I made an example on How to read and write XML using XDTO.

To set a reference for a new object, you can use the SetNewObjectRef method of the object and to create a reference by UUID, you can use the GetRef method of the manager of that object type:
Code
NewObject.SetNewObjectRef(Documents.IngresoDeBienes.GetRef(New UUID(RefAsString)));

 
#6
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

There is no way to read XML using XDTO without second parameter? What is the point of XDTO and definitions then if I have to define everything manually?! I need XDTOSerialization mechanism for non-platform types.

 
#7
People who like this:0Yes/0No
Timofey Bugaevsky
Guest

Joined:
Company:

Alexey, if you need to serialize and deserialize infobase objects automatically, you can use the XDTO serializer.
Here is an example for JSON, but the same you can use for XML:
HTTP Services and JSON.

 
#8
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

But will it work for custom objects (not from configuration)? The problem is that I have different objects in configurations, so I need intermediate object (just for exchange) with some attributes and I have rules in both configuration to convert exchange object to configuration object. That is why I have hopes for XDTO.

We have been using XDTOSerializer for importing configuration objects and it is no go for different configurations. if I add just one parameter to one configuration (or the user wants to add) it will require changes to another configuration although new field could be just additional comment which does not make sense to synchronize to mobile.

I think XDTO ReadXML should understand the type of objects it is reading. In my example XML file clearly defines via "xmlns" field and its name what object it is. I can not use your suggestion #5 because simply I do not know which object is next. So by reading its type I could suggest further actions. I could implement this behavior by reading raw XML, but it is a lot of extra code which seems unnecessary.

Also I have found several publication (on Inforstart) which claim that automatic type suggestion should work, but there are no clear example how to make it work.

 
#9
People who like this:0Yes/0No
Timofey Bugaevsky
Guest

Joined:
Company:

Alexey, in case of using custom objects, you need to define them in the Configuration tree: Common/XDTO packages. And then in the source application you can add web services, that use those packages and in the target one you need to add WS-references to your web services.

You can find more examples in Web services demo.

 
#10
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

Timofey, they are defined in the configuration tree. In Common/XDTO packages. Please look again at the configuration I have sent you.
There is no problem with Web services / exchanging information. The only problem is that the platform does not recognize types of XDTO objects read from XML.

Please modify the configuration I have sent you to read at least one XDTO object from XML using XDTO Refernce, XML Schema or XDTO Data Model (I really don't care which one to use) but WITHOUT defining object type in code like you suggested in #5. It should be possible. All the information needed is provided in XML and Schema (or XDTO reference).

Please help me with this one. If you say that is impossible I'll be forced to write low-level XML parser to basically implement logical XDTO behavior.

 
#11
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

I have reviewed the example you suggest. There is no code in this example which shows how to write / read to/from XML. I can not omit writing to XML because it is used in standard changes registration mechanism.

Also it seems to me that an example is not very good. It transmit one big XDTO object with hierarchy (root item). This could provoke out of memory if you transfer a greater sized catalog.

 
#12
People who like this:0Yes/0No
Timofey Bugaevsky
Guest

Joined:
Company:

Hello, Alexey.

Do you have a valid XML schema for your data? XDTO needs a description of data to read the format. In your example there was only data. That is why gave a link to an example with XDTO packages.

 
#13
People who like this:0Yes/0No
Interested
Rating: 34
Joined: Oct 27, 2011
Company: Abaco Soluciones S.A.

Timofey, the first message:

Quote
p.s. I have attached schema and xml example so you can test it.

 
#14
People who like this:0Yes/0No
Timofey Bugaevsky
Guest

Joined:
Company:

Hello, Alexey.

Here I made a simple example on how to make serialization of configuration objects into XML and reading them back.
You can use XDTOSerializer object and if the types that you use present in XDTO packages (built in or added by you), then your objects will be written and read without need to specify types.

Please see the attached infobase dump.

Code
&AtServerNoContext
Function ExportXMLAtServer()
   
   XMLWriter = New XMLWriter;
   XMLWriter.SetString("UTF-8");
   XMLWriter.WriteXMLDeclaration();
   XMLWriter.WriteStartElement("v8msg:Message");
   XMLWriter.WriteNamespaceMapping("v8msg", "http://v8.1c.ru/messages");
   XMLWriter.WriteStartElement("v8msg:Body");

   Query = New Query;
   Query.Text = 
      "SELECT
      |   SalesOrder.Ref
      |FROM
      |   Document.SalesOrder AS SalesOrder";
   
   QueryResult = Query.Execute();
   
   SelectionDetailRecords = QueryResult.Select();
   
   While SelectionDetailRecords.Next() Do
      Object = SelectionDetailRecords.Ref.GetObject();
      XDTOSerializer.WriteXML(XMLWriter, Object, XMLTypeAssignment.Explicit);
   EndDo;
   
   XMLWriter.WriteEndElement();
   XMLWriter.WriteEndElement();
   
   Return XMLWriter.Close();
   
EndFunction

&AtServerNoContext
Procedure ImportXMLAtServer(XML)
   
   XMLReader = New XMLReader;
   XMLReader.SetString(XML);

   XMLReader.Read();
   
   Data = XDTOFactory.ReadXML(XMLReader);

   For Each XDTODocument In Data.Body.DocumentObject_SalesOrder Do
      Document = XDTOSerializer.ReadXDTO(XDTODocument);
      Object = Undefined;
      If Document.Ref.IsEmpty() Then
         Object = Documents.SalesOrder.CreateDocument();
      Else
         Object = Document.Ref.GetObject();
      EndIf;
      FillPropertyValues(Object, Document);
      Object.Write();
   EndDo;
      
EndProcedure

Download xdto.dt (38.88 KB)
 
Subscribe
Be the first to know tips & trick on business application development!

A confirmation e-mail has been sent to the e-mail address you provided .

Click the link in the e-mail to confirm and activate the subscription.