Reading XML files using XDTO

Publications: Reading XML files using XDTOIf you are a developer 1C or write in PHP, or C++, it does not matter, but sooner or later you will be faced with XML. Why? Because it is universal, convenient, ubiquitous, cool, cross-platform . XML correctly understands in Android, Windows and Linux, etc. It is used for the exchange of information. It is used to store information.
In this post, I will explain how to read XML using 1C mechanism XDTO. You can see that the code is very simple, and no conversion is not required for XML values.

“Now, here, you see, it takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!”
Red Queen

Do not know why I put it here :).

With problem of the read / write XML I have encountered in connection with the integration of corporate websites of various companies with 1C, namely, customers want to exchange some information between 1C and their site, and do it with some frequency. Typically, these were sales (information for managers), orders (for dealers) and various data like log requests, tasks, reports, etc.

EXAMPLE I.

Let us suppose such a task, let the students are registered on the site of a certain educational institution (no matter what may be to get tested or something else). The manager wants to put the data in the 1C catalog “Students”. PHP programmer said “No problem!” and gave a XML file like this:



	
		John 
		Smith 
		Male
		1986-05-11
		2
		123
	

Here, the root element is the “students”. Subelement is “student”, which contains basic information about the student. Elements “name”, “last_name”, “sex”, “comment” are of type “string”, “birth” - “date”, “level” - “integer”. We need to read this data and write in the catalog “Students” of our infobase.

How to read? You can use the “XMLReader” , but then you will need to process a document line by line. And it is good if nesting levels only 2-3. But if they are 10 and 10 thousand lines? You can be processed using “DOMDocument” which creates us some tree representation of the document XML. But then we will need to process each item separately, you will need to write code to convert the element to correct type. It is not our method . Let’s try to create a XDTO-package and read by it our XML file. To do this, I created a new configuration with the following objects :
Publications: Reading XML files using XDTO

I created XDTO package “Students”:
Publications: Reading XML files using XDTO

And I defined a namespace “http: //localhost/xdto”. What is namespace? Check Wkipedia!

In this package I described the XML scheme. You can even right-click on the package and export the schema (file extension “.xsd”). For properties I also have types: name, last_name, sex, comment are of type “string” (http://www.w3.org/2001/XMLSchema). As you can see, the string type is also defined in some namespace, namely his determined together on conference w3 standard. The property “birth” has a date type (http: //www.w3.org/2001/XMLSchema), level - integer (http: //www.w3.org/2001/XMLSchema). How this is done you can look at example infobase (link at the end of this article).

Also you can define this schema this way:
Publications: Reading XML files using XDTO

The difference is only one, I created a type “type_student” and identified the type of “student” property. This is called explicit type definition. And before that was implicit type definition. And now let’s read XML and create elements in catalog. To do this, I created a data processor “XMLReading”, which can also look in example, here I give only the code:

&AtClient 
Procedure OneStudent(Commant)
	
	OneStudentServer(XML);
	
EndProcedure 

&AtServerNoContext  
Procedure OneStudentServer(XML)
	
	// get XDTO type for students and read XML 	
	stType = XDTOFactory.Type("http://localhost/xdto", "students");
	
	oReadXML = New XMLReader;
	oReadXML.SetString(XML);
	
	ObjectXDTO = XDTOFactory.ReadXML(oReadXML, stType);
	
	FirstStudent = ObjectXDTO.student;
	
	// Check if this student already exists in the database
	Query = New Query("SELECT
	                  |	Students.Ref
	                  |FROM
	                  |	Catalog.Students AS Students
	                  |WHERE
	                  |	Students.FirstName LIKE ""%"" + &FirstName + ""%""
	                  |	AND Students.LastName LIKE ""%"" + &LastName + ""%""
	                  |	AND Students.BurthDate = &BurthDate");
	
	Query.SetParameter("FirstName", FirstStudent.name);
	Query.SetParameter("LastName", 	FirstStudent.last_name);
	Query.SetParameter("BurthDate", FirstStudent.birth);
	
	Result = Query.Execute();
	
	If Result.IsEmpty() Then 		
		objStudent = Catalogs.Students.CreateItem();
	Else	
		Selection = Result.Select();
		While Selection.Next() Do 			
			objStudent = Selection.Ref.GetObject();
			Break;
		EndDo;
	EndIf;

	// Fill attributes	
	objStudent.FirstName 	= FirstStudent.name;
	objStudent.LastName 	= FirstStudent.last_name;
	objStudent.BurthDate 	= FirstStudent.birth;
	objStudent.Sex 			= FirstStudent.sex;
	objStudent.Level 		= FirstStudent.level;
	objStudent.Comment 		= FirstStudent.Comment;
	
	objStudent.Write();
	
EndProcedure

You can see that the code is very simple, and no conversion readed XML elements is not required, it does XDTOFactory. Well, let’s use our data processor and check whether there will be a new entry in the catalog “Students”. Error!
Publications: Reading XML files using XDTO

The fact that we do not specify XML namespaces.
Let’s take the XML, which I quoted above, and add:



	
		John 
		Smith 
		Male
		1986-05-11
		2
		123
	

EXAMPLE II

Let us assume that the XML contain not one student but several:



	
		John 
		Smith 
		Male
		1986-05-11
		2
		123
	
	
		Brad 
		Pitt 
		Male
		1960-01-11
		3
		
	

If you try to read it with a scheme which we did, you get an error, and rightly so, we are not defined in the scheme that there may be many students. Let’s fix this situation by modifying the property “student”:
Publications: Reading XML files using XDTO

Please note, that property “Maximum number” I changed to “-1”, it means that the property “student” able contain unlimited number. If we set this property to “3”, the count of “student” can not be more than 3, etc.
Launch data processor and everything works!
Publications: Reading XML files using XDTO

Here the modified code. Of course, it is strongly not recommended to put a query in the cycle, but I do not want to do some optimization:

&AtClient
Procedure ReadManyStudents(Command)
	ReadManyStudentsAtServer();
EndProcedure

&AtServer
Procedure ReadManyStudentsAtServer()
	
	// get XDTO type for students and read XML 	
	stType = XDTOFactory.Type("http://localhost/xdto", "students");
	
	oReadXML = New XMLReader;
	oReadXML.SetString(XML);
	
	ObjectXDTO = XDTOFactory.ReadXML(oReadXML, stType);
	
	For Each FirstStudent In ObjectXDTO.student Do 	
		
		// Check if this student already exists in the database
		Query = New Query("SELECT
		                  |	Students.Ref
		                  |FROM
		                  |	Catalog.Students AS Students
		                  |WHERE
		                  |	Students.FirstName LIKE ""%"" + &FirstName + ""%""
		                  |	AND Students.LastName LIKE ""%"" + &LastName + ""%""
		                  |	AND Students.BurthDate = &BurthDate");
		
		Query.SetParameter("FirstName", FirstStudent.name);
		Query.SetParameter("LastName", 	FirstStudent.last_name);
		Query.SetParameter("BurthDate", FirstStudent.birth);
		
		Result = Query.Execute();
		
		If Result.IsEmpty() Then 	
			
			objStudent = Catalogs.Students.CreateItem();
			
		Else	
			
			Selection = Result.Select();
			While Selection.Next() Do 			
				objStudent = Selection.Ref.GetObject();
				Break;
			EndDo;
			
		EndIf;
		
		// Fill attributes	
		objStudent.FirstName 	= FirstStudent.name;
		objStudent.LastName 	= FirstStudent.last_name;
		objStudent.BurthDate 	= FirstStudent.birth;
		objStudent.Sex 			= FirstStudent.sex;
		objStudent.Level 		= FirstStudent.level;
		objStudent.Comment 		= FirstStudent.Comment;
		
		objStudent.Write();
		
	EndDo;
	
EndProcedure

EXAMPLE III

Suppose we have XML, where there is no information on students (this case also happen sometimes). The XML text below:



Try to read it by our data processor. What is gained? Error!
Publications: Reading XML files using XDTO

And it is correct! We are specified in the factory that elements students can be from one to infinity. And here we have zero, so it is mistake. Let’s fix this moment:
Publications: Reading XML files using XDTO

I did the minimum number is zero and a maximum number -1, ie unlimited. Now everything is working properly.

EXAMPLE IV

All! We have provided all cases! You can go to drink tea…;). But then we get another XML:



	
		John 
		Smith 
		Male
		1986-05-11
		2
		123
		!!
	
	
		Brad 
		Pitt 
		Male
		1960-01-11
		3
		
		!!
	

Insert XML in a text box, click “Read many students.” What we get? The error!
Publications: Reading XML files using XDTO

And why error? Look at the XML. There is a new element “new_field”, which is not included in our factory. What to do? You can include it in our scheme, but what if the file will come again with another element XML? This case can be processed in the following way - open in a factory “type_student” property and set “Open” = “Yes”:
Publications: Reading XML files using XDTO

Well that’s all. Now you can read XML without any problems. Now tag “student” may contain besides given any other tags and they will be read as a string type. Link to example of this information base below the publication.

[Total: 0    Average: 0/5]

Leave a Reply

Your email address will not be published. Required fields are marked *