Desktop version

Main > Forum > 1C:Enterprise Platform > 1C:Integration > XDTO XMLRead just reads AnyType Or String

Forum

Search UsersRules
XDTO XMLRead just reads AnyType Or String
#1
Interested
Points:: 15
Joined:: Oct 27, 2011

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.

Profile
#2
Interested
Points:: 15
Joined:: Oct 27, 2011

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

Profile
#3
Guest
Points::
Joined::

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.

Profile
#4
Interested
Points:: 15
Joined:: Oct 27, 2011

8.3.8.1933

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

Profile
#5
Guest
Points::
Joined::

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)));

Profile
#6
Interested
Points:: 15
Joined:: Oct 27, 2011

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.

Profile
#7
Guest
Points::
Joined::

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.

Profile
#8
Interested
Points:: 15
Joined:: Oct 27, 2011

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.

Profile
#9
Guest
Points::
Joined::

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.

Profile
#10
Interested
Points:: 15
Joined:: Oct 27, 2011

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.

Profile
#11
Interested
Points:: 15
Joined:: Oct 27, 2011

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.

Profile
#12
Guest
Points::
Joined::

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.

Profile
#13
Interested
Points:: 15
Joined:: Oct 27, 2011

Timofey, the first message:

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

Profile
#14
Guest
Points::
Joined::

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

Profile
Subscribe
Users browsing this topic (guests: 1, registered: 0, hidden: 0)



© 1C LLC. All rights reserved
1C Company respects the privacy of our customers and visitors
to our Web-site.