Menu
Is free
registration
home  /  Problems/ Guide to the Internet - all the fun on the net. Using XML Document Object Model How to create a delphi xml file

Internet travel guide - all the fun on the web. Using XML Document Object Model How to create a delphi xml file

ORDER A SOLUTION TO DELPHI
Delphi is the second most important programming language that students are most often introduced to in the learning process. This is the beginning of learning about object-oriented programming. As a student, I came to the conclusion that there is no easier method to learn a language than to write a calculator in it. Even if you implement a rudimentary function for adding two numbers, it will shed light on a lot.

CodeGaear, Delphi 7, Lazarus are different compilers, programs that will transfer the code you write to the machine, converting it to ones and ones. These are all programs for creating programs, not separate programming languages. These compilers use the Object Pascal programming language, which is the basis of the Delphi language, which is similar in syntax to ordinary Pascal, but functionally differs significantly.

What is the syntax of a programming language?

This is the format for writing various operators. For example, a Pascal for loop has the following format: for n: = 1 to k do, and so on.

In the C ++ programming language, the same loop is written a little differently: for (n = 1; n We write a calculator

This will give you an understanding of how objects interact with program code, what "variables" are, and how mathematical functions work. Any programming will in any case be a computation. A game is also a program that constantly calculates something, works with numbers and numerical functions. Programming is inseparable from mathematics.

Let's use the Lazarus development environment for writing. Its functionality is not as rich as, say, CodeGear, but it is freely available and is intended for training.

Opening the development environment, we see the form and the toolbox. Here is the form.

Here is the toolbox.

The first thing we will do is add the three elements we need to implement the function for adding two numbers. We need: "Tedit" in the amount of three pieces and "TButton". In the picture below they are shown on the panel with arrows. We click on them once, and then once on the form, and they appear on it.

These are text fields for input and a regular button. You come across these elements using almost any Windows program... Take a look.


Now let's clear these labels. Click the "View" tab. And click on the item "Object Inspector. A window like this will appear.

We click once on our "Button" element on the form and change the "Caption" value in the inspector window to any other. For example, the word "Ok". We press Enter. We see on the form how the element has changed its name.

Let's do the same with Edit's, just don't rename them, but make them without any content. Select them one by one and clear the Text value in the inspector. Do not forget to press Enter.

As a result, our form looks like this.


Now, for our calculator to work, you need to register the required program code for our button procedure. Click on the Button element twice and open the source editor.

See? Procedure Button1Click. This is the procedure that is responsible for what happens when we click on the button once. And the following should happen: the program needs to display the sum of the numbers entered in the first two fields in the third Edit. We write the code.

We need to write such simple 5 lines of code. Comments and explanations can be seen in the picture above. After that, we press this button.

Our project will be compiled. It will be compiled into a program. We enter numbers in the first two fields, click on the button and get the value of the sum.

Conclusion

You can click the "File" button, then "Save All", select a folder to save and you will have a full-fledged program that can be launched from the desktop. Now try to figure out for yourself what you need to rewrite in this code so that the program divides two numbers, and does not add. Hint: you need to change the data type. The video below shows a similar example, but in the Delphi 7 environment, not Lazarus.

For many Delphi programmers, saving settings is associated with using INI files in their programs. Application this method, in more or less serious projects, should be avoided, as this limits flexibility, which prevents further expansion of the program. It should be said that this approach is quite popular due to its ease of use and the presence of built-in tools in the development environment.

However, structured XML files. Their advantage is that the number of parameters may not be fixed. To understand this better, consider a specific example.

In the USearch program, when you click on an entry, a context menu appears, which displays a list of items. These items are commands, which in turn are loaded from the settings file. In case the settings were stored in INI file, then the program could save and load a certain number of commands, for example 10 or 50. As soon as a larger value is required, you will have to rewrite the code and re-compile it accordingly.


Applying an approach using XML files, we will be able to load all section parameters dynamically. In addition, the configuration file will become more elegant, without redundant parameter numbering. But, standard means to work with XML Delphi has many disadvantages, so I recommend using standard library MSXML... It is usually included by default in operating systems Windows family.


To connect MSXML, we need to create an interface file with a list of all functions by importing it from the COM server. Many detailed articles have been written on how to import the interface, but I suggest you download the file MSXML2_TLB.PAS ready to use. After the file is downloaded, place it next to your project, or drop it into the lib folder of the Delphi environment. So all created programs will be able to use the module MSXML, you just need to add the MSXML2_TLB line to uses.

For clarity, consider the following example of using this library:

Procedure LoadData; var XMLDoc: DOMDocument; Root: IXMLDOMElement; begin XMLDoc: = CoDOMDocument.Create; XMLDoc.Load ("settins.xml"); Root: = XMLDoc.DocumentElement; ShowMessage (Root.SelectSingleNode ("size / width"). Text); Root: = nil; XMLDoc: = nil; end;

First, an instance of the DOMDocument class is created, and then the contents of the settings.xml file are loaded into memory. Since by the standard any XML the file must contain the root tag (in this case config), then we need to get it using the function DocumentElement... Then the content is displayed between the tags. , which in turn are between the tags ... Thus, from the settings.xml file, our method will display the text in the MessageBox "100px".

500px 100px

Here the SelectSingleNode method is applied, which takes a string as a parameter

Welcome! This blog is about the Internet and computers, or rather it was dedicated to them.

Probably, it is immediately clear that no new articles have appeared on the site for many years. Yes, that's the fate of most blogs. This project was once an ambitious undertaking, and the author, like many others who wrote at the time, had ambitious plans to become one of the best Russian bloggers. Well, if you look now, then of those blogs that were created simultaneously with mine, most have already disappeared into eternity. And I just didn't have enough time to blog. So yes, it is not being updated anymore. Although once we with this site won the competition "Blog of Runet 2011".

I even had an idea to delete all this, but then I revised the old materials, and realized that they can still be useful to readers. Yes, some articles are outdated (if I have enough strength, they will receive appropriate notes), but the site, for example, can be useful for beginners - here you can read about basic concepts Internet, learn how to configure the Internet, Windows, or even decide to switch to Linux. So look at the rubrics and choose the one that's right for you.

And yet, I hope this is more than just a blog, but a real guide to the Internet. The site can be viewed in the directory mode, where all available articles are structured by category. And who knows, maybe one day new high-quality articles will start appearing here.

Sander

Picodi.ru is a discount portal from International Coupons, a Polish expert in savings and cheap shopping. Poles are considered one of the most economical nations in the world, so it is not surprising that this type of project grew out of the Polish startup kodyrabatowe.pl. How can this portal be useful to an ordinary Internet user in Russia?

Modern android phones are more than phones. You get used to typing installed programs, to your call and text message history, photo collection and more. But time passes, and the device that suits you completely begins to slow down, glitch, or simply loses its presentable appearance due to chips on the case or scratches on the screen. The question arises of choosing a new phone and changing android phone... And if we now bypass the question of choice, then "moving" to new phone remains a serious problem - you absolutely do not want to start all the data from scratch. This is what we are going to talk about today.

Most of the readers of this blog, most likely, have never encountered version control systems and will not come across any in the near future. It's a pity. This extremely convenient invention is widely used by programmers, but, in my opinion, it could be very useful for those who actively work with texts. But, probably, now there is not a single version control system that would be easy to start using for the "office" ( Microsoft Office) work. Nevertheless, I think that the material presented in the article may be interesting for all readers.

If you have thought about how to watch movies on the network from your TV and go online, this article is for you. No, I know that some TVs already have Smart TV functionality, but I have never seen it work properly. Apparently, therefore, recently the Google corporation demonstrated an absolutely stunning device, which immediately became a sensation. We're talking about the Chromecast media streamer (Chromecast), a more advanced and affordable version of last year's disastrous Nexus Q.

Dongle Chromcast, which is no more than 2 inches in size, plugs into the port HDMI TV and allows you to enjoy watching streaming web content. To control the streamer, you can use any device (tablet, PC, smartphone) based on the operating platform iOS, Windows, Android or Mac OS.

This article is about the device system memory android, problems that may arise due to its lack and ways to solve them. I myself recently came across the fact that my android phone began to regularly give out messages about insufficient memory when trying to install an application. Which was very strange for me, given that according to the description on the market there should have been about 16GB, and I also increased this volume with an additional memory card. However, there was a problem, and I had to tinker a lot before I found the correct solution that did not require root access or full recovery phone back to factory condition.

Recently, much attention has been paid to the construction of e-business systems, or as they are also called - B2B (business to business). Considering the recommendations for the construction of exchange streaming systems of the coordinating body of Internet technologies - WWW Consortium: the emphasis is on XML technologies and the construction of systems for the exchange of XML documents.

The advantage of using XML in electronic business- high efficiency of B2B systems at low costs for its creation due to a clear and visual presentation of structured information, the ability to use modern network protocols and the creation of real-time business systems.

The independence of the presentation of information in the form XML documents allows different companies involved in e-business to produce software independent of each other.

In all systems, the exchange, as a rule, is built according to the same scheme, using HTTP requests. The SSL protocol is used as the information security protocol (but this is a separate topic).

One of possible options XML message processing is the construction of BIN / CGI (ISAPI) applications or COM (server) components that form or process XML documents.

On the one hand, the application acts as a client, which issues an HTTP request in POST mode, on the other hand, there is a WEB server on the side of which the request is processed and a response is issued. The information exchange uses XML documents.

One of the most efficient implementation options is to use an existing XML parser that supports the DOM model. Such a parser is a distribution distribution of Win'98 or part of IE 4.7 and higher (for Win`95) and represents the COM server located in the msxml.dll library.

Component Object Model (COM) - presents encapsulated data and methods into a single entity and a way to access them through a system of interfaces. Using Delphi tools, it is quite easy to access the classes of a COM object (several classes can be included in one COM server). Objects are accessed by initializing an instance of the class through the interface system. The description of interfaces is carried out by the interface definition language (IDL), which can be carried out automatically by means of the environment.

Delphi tools are used to import from a COM server msxml.dll, the files for the description of the IDL interface and the file for the binary description of the library types - TLB are built. This operation carried out through the system menu: Project | Type Library Import:(picture 1). Next, a dialog box appears (Figure 2), in which you need to select a COM object (in our case, the object is registered under the name "Microsoft.XMLDom (Version 2.0)") and create a TLB file (button Create Unit). Using the TLB file, the framework generates a Pascal COM server description file - MSXML_TLB.pas

The MSXML_TLB.pas file describes all the interfaces, constants, and coclasses of the COM server.

To access objects of a COM element, you need in the directive USES add the name of the library description file (MSXML_TLB.pas). Below is a simple program using the standard DOM parser msxml.dll, which loads an XML document and displays it in a Memo1 text field element.

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, OleServer, MSXML_TLB, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click (Sender: TObject); end; var Form1: TForm1; implementation($ R * .DFM) Procedure TForm1.Button1Click (Sender: Tobject); // declaration of the soclass of the DOMDocument object; var coDoc: CoDOMDocument; // class consistent with the IDOMDocument interface; var Doc: IXMLDOMDocument; begin // create an instance of the DOMDocument object; Doc: = coDoc.Create; // call the Load method of an instance of the DOMDocument object; Doc.load ("data.xml"); // access the xml property of the DOMDocument instance; Memo1.Text: = Doc.xml; end; end.

DOM Concept - Document Object Model

Each XML document is represented as a set of many objects (classes), with the help of which it is possible to access individual elements(object fields). DOM - the interface describes access to both simple objects such as DOMString or CharacterData, and to parts or separate XML elements document: DOMFragmentElement, DOMNode, DOMElement.

Following are the most important properties and methods of XMLDOMDocument, XMLDOMNode, XMLDOMNodeList objects. It should be noted that the methods and functions of DOM objects presented below (Document Object Model) are used by the Microsoft XML parser msxml.dll and are somewhat broader than the model approved by the W3C DOM Consortium.

More Full description DOM objects interface can be found at

XMLDOMDocument object
Represents the top level of the object hierarchy and contains methods for working with a document: loading it, analyzing it, creating elements, attributes, comments, etc. ...
Properties
Async Property identifying the current processing mode
ParseError Returns a reference to the XMLDOMParseError error handling object
Enable - disable document verification.
url Returns the URL of the document
documentElement Contains a reference to the root element of the document as an XMLDOMElement object.
Methods
load (url)
loadXML (xmlString)
Loads an XML document,
save (objTarget) Saves XML document to file
abort Interruption of the process of loading and processing the document.
createAttribute (name) Creates a new attribute with the specified name for the current element.
createNode (Type, name, nameSpaceURI) Creates a node of the specified type and name
createElement (tagName) Creates a document element with the specified name.
createTextNode (data) Creates text within a document
getElementsByTagName (tagname) Returns a reference to the collection of document elements with the given name
nodeFromID (idString) Finding an item by ID

XMLDOMNode object
XMLDOMNode object that implements the basic DOM interface Node, is intended for manipulating a separate node of the document tree. Its properties and methods allow you to get and change complete information about the current node - its type, name, full name, its contents, list of child elements, etc.
Properties
nodeName, baseName Returns the name of the current node.
prefix Returns the Namespace prefix.
dataType Specifies the content type of the current node
nodeType, nodeTypeString Returns the type of the current node:
attributes Gets a list of the attributes of the current node as an XMLDOMNamedNodeMap collection.
text Returns the contents of the current subtree as text
xml Returns an XML representation of the current subtree.
nodeValue Returns the contents of the current node.
childNodes Returns a list of child elements as XMLDOMNodeList.
firstChild, lastChild Returns the first / last child
previousSibling, nextSibling Returns the previous / next sibling element.
parentNode Contains a link to the parent element.
ownerDocument Returns a pointer to the document containing the current node.
Methods
appendChild (newChild) Adds a new child to the current node.
insertBefore (newChild, refChild) Inserts a child node, positioning it in the current subtree to the left of the node specified by refChild.
cloneNode (deep) Creates a copy of the current item.
getAttribute(name)
getAttributeNode(name)
setAttribute (name, value)
setAttributeNode (XMLDOMAttribute)
Access to attributes (create, read, write) of the object. Name is the name of the attribute, value is its value. Returns the value of an XMLDOMAttribute object.
replaceChild (newChild, oldChild) removeChild (oldChild) Replacing the oldChild object of the current list of child objects with newChild. Deleting oldChild object
selectNodes (patternString) selectSingleNode (patternString) Returns XMLDOMNodeList object, selected by search pattern or first node
transformNode (stylesheet)
transformNodeToObject (stylesheet, outputObject)
Assigns a style sheet to the subtree of the current node and returns a string representing the result of the processing. The parameter is a reference to the DOMDocument object that contains the XSL statements.

Using XML in Business.

For a clearer picture, an explanation is needed, and why all this is needed in order to understand how it works:

When building a B2B or corporate ERP system, when organizing information exchange of XML documents between enterprises or branches of the pr-I, an efficiently proven system of information transfer based on existing WEB servers over HTTP protocols is used.

On the one hand, the application acts as a client, which issues an HTTP request in POST mode, on the other hand, there is a WEB server, on the side of which the request is processed and a response is issued. XML documents are used as an exchange.

For example, in a simple corporate ERP system, an accounting program (ACS Accounting), it is necessary to form a request for an invoice and send it to a branch that has a warehouse (ACS Warehouse). AWP A similar problem statement when creating a B2B system, when Enterprise A requests the availability of products (makes an order for the purchase) from Supplier B.

Enterprise A and its program act as a client. The warehouse is served by Supplier B, who has a warehouse complex with a database on a SQL server. The exchange is carried out through the corporate WEB server of the Supplier V.

Below is the following typical exchange algorithm:


Figure 3.
  1. Enterprise A initiates process A(product order), which acts as a WEB client.
  2. Process A generates an XML document (for example, an invoice request) and transmits it as a POST http request to the WEB server of Provider B. As a URI, the resource identifier of the processing application is used. The URI can be the same for all types of documents, or individual for each type. It all depends on the structure of the B2B (WEB) server.
  3. WEB server analyzes the request and generates a server Process B by passing the body of the XML document as a parameter.
    Process B is launched by a WEB server and is processed either as an ASP page, CGI (ISAPI) - application or JAVA server (server application)
  4. Process B- generates a request to the SQL database server.
  5. The SQL server performs the necessary operations in the database, generates a response and returns it Process B.
  6. According to the response from the SQL server Process B generates an XML document (response) and returns it as a response to an http request to the client application.
  7. Further, depending on the situation on the client side, either a new http request is formed, or the session ends.

A few words about the organization of document flow.

The general rule for developing a system for exchanging XML documents is:

  • At first- development of a flow chart of electronic documents and their structure;
  • Secondly- development of tables of process functions (sub-processes), i.e. what function each process will implement with respect to what XML document.

Each XML document, like an HTML document, must consist of a message header (information enclosed by tags) and a message body (for a request, this information is framed with tags to respond to a request). In order for the XML document to be well formed, it is necessary to frame its two component parts "Title" and "Request" with tags, for example. The type of a typical document is presented below:

The header (Figure 4), in contrast to an HTML document, must contain various kinds of service information, including information about the type of the transmitted document and the process of its processing. The body of the document enters information processing, i.e. content framed by tags. It should be noted that the structure of headings should be the same for all types of documents.

For the Process started by the server, it is preferable (but not necessary) to build the processing algorithm as follows:


Figure 6.

Some fundamental points when creating the client side

As already explained, when creating an XML document, its representation in the form of a DOM model is used. Below is an example of a Delphi text portion of a message xml header generating program.

procedure TThread1.HeaderCreate (Sender: Tobject); var // class declaration, needed to create coDoc: CoDomDocument; // XMLDomDocument object Doc: DomDocument; r: IXMLDOMElement; Node: IXMLDOMElement; // DOMText txt: IXMLDOMText; // DOMAttribute attr: IXMLDOMAttribute; begin // create DOM document Doc: = coDoc.Create; Doc.Set_async (false); // initial initiation of the DOM document Doc.LoadXML ("
"); // create DOMElement (tag<Sender>) Node: = Doc.createElement ("Sender"); // create a text node " Typhoon LLC" txt: = Doc.createTextNode ("Typhoon LLC"); // assignment to node<Sender> value // text node " Typhoon LLC" Node.appendChild (txt); // add element<Sender> to the document root as a child r.appendChild (Node); <From> Node: = Doc.createElement ("From"); txt: = Doc.createTextNode ("http://tayfun.ru/xml/default.asp"); Node.appendChild (txt); r.appendChild (Node); // similar operations for the tag<To> Node: = Doc.createElement ("To"); txt: = Doc.createTextNode ("http://irbis.ru"); Node.appendChild (txt); r.appendChild (Node); // create DOMElement () Node: = Doc.createElement ("TypeDocument"); // create XMLDOMAttribute node Att: = Doc.createAttribute ("Id", "Order"); // Node.appendChild (Att); r.appendChild (Node); end;

It should be noted that the declaration of the variable coDoc: CoDomDocument and Doc: DomDocument, as well as its creation by the Create method (Doc: = coDoc.Create;) is done once. The variable declaration is located in the section describing global variables, and not in the local procedure, as it was demonstrated for clarity in this example (that is, one global variable of the DomDocument type per one program module).

The result of the work of the above program will be the created header, applied to our example xml document: shown in Figure 5.


Figure 5.


Figure 6.

The main advantage of transferring information in the form of XML documents is that it is possible to form a message using independent table structures in the DBMS both on the receiving and on the transmitted side. Using our example, suppose it is required to transfer information about the invoices of Enterprise A, from the DBMS having the structure shown in Figure 6

To generate an xml document containing an invoice, an SQL query (query A) is initially built with information about the invoice itself:

SELECT* FROM Invoice_General WHERE InvoiceNum =: num SELECT Goods, Qulity, Price, HZ_cod FROM Goods WHERE InvoiceNum =: num //: num is a parameter that specifies the invoice number.

Below is a part of the program that generates the body of the xml document:

procedure TThread1.DataBodyCreate (Sender: Tobject); var // declaration of the class and the XMLDomDocument object// coDoc: CoDomDocument; // must be global for the whole module.// Doc: DomDocument; // declare DOMElement objects r: IXMLDOMElement; // DOMElement; Node, Node2: IXMLDOMElement; Node3, Node4: IXMLDOMElement; // DOMText txt: IXMLDOMText; str: String; // InvoiceNumber: integer;- global variable - // has the value 987654 // queryA, queryB: String;- global variable, // has a value corresponding to the query // queryA - query A with general information about the invoice // queryB - query B information about the goods described in the invoice (see text) begin Query.Close; // see the text "request A" Query.Text: = queryA; // execute the request Query.ExecSQL; Query.Open; // get the address of the root element r: = Doc.Get_documentElement; Node2: = Doc.createElement ("Request"); // create DOMElement (tag) Node: = Doc.createElement ("Invoice"); // add an element to the root r.appendChild (Node2); // add an item to Node2. appendChild (Node); // create DOMElement (tag) Node3: = Doc.createElement ("Depurture"); // add an item to Node. appendChild (Node3); // call to the "Depurture" field of the request str: = Query.FieldByName ("Depurture"). AsString; // create text node = field value// assign a value to the node // text node, variable str Node.appendChild (txt); // similar operations for the tag , , // , // (DB field "Consignee") Node: = Doc.createElement ("Destination"); // the name of the database field may not be the same as the name str: = Query.FieldByName ("Consignee") .AsString; // tag, this is the advantage of using txt: = Doc.createTextNode (str); // DOM of the interface in front of a DBMS that supports XML interface, // like ORACLE 8i or Ms SQL 2000 Node.appendChild (txt); ... // generating a request for a specification for goods // close the request for access Query.Close; // see in the text "request B", info. About goods Query.Text: = queryВ; // assignment of parameter values Query.Params.AsInteger: = InvoiceNumber; // execute the request Query2.ExecSQL; // open access to request data Query.Open; // create DOMElement (tag) Node3: = Doc.createElement ("Imems"); // add an item to Node. appendChild (Node3); // loop through all lines of the query while not Eof.Query do begin Node4: = Doc.createElement ("Imem"); // add an item to Node3.appendChild (Node4); // generating data for the tag str: = Query.FieldByName ("Price"). AsString; txt: = Doc.createTextNode (str); Node.appendChild (txt); ... // similar operations for tags , , end; end;

As a result of this procedure, the following text of an XML document is generated:


To form a request, the Open method of the object is used IXMLHttpRequest:

procedure Open (const bstrMethod, - method type = "POST" bstrUrl, - Server url varAsync, - asynchronous / synchronous communication mode = true bstrUser, - username for authentication bstrPassword) - password

Creating the server side of document processing

As noted earlier, processing HTTP request can be implemented by either CGI applications or Java servlets. The variant of writing ASP-pages is also possible. But in this case, data transfer is possible only by the "GET" method through the query string. However, handling an HTTP request for ASP pages is more efficient than a CGI application. However, in my opinion, it does not matter how to process it, but it is more important to solve the question - how to build a processing program, and not by what means.

If from the previous chapter we examined the options for forming an XML document, then the task of the server application is the opposite - parsing XML documents. Below is a part of the program that parses an xml document:

procedure Tthread1.DataParser (Sender: Tobject); var // declare DOMElement objects r, FNode: IXMLDOMElement; Str, Filename: String; parm: String; // soclass declaration and CoDocXML, CoDocXSL, CoDocResult: CoDomDocument; // XMLDomDocument object XMLDoc, XSLDoc, ResultDoc: DomDocument; // HttpStr: String; - a global variable containing the HTTP request string Begin XMLDoc: = coDocXML.Create; XMLDoc.LoadXML (HttpStr); // get the address of the root element r: = Doc.Get_documentElement; // get the value of the element FNode: = r.SelectSingleNode ("// TypeDocument"); // get the value of the attribute id = "Order" FileName: = FNode.GetAttibute ("id"); // and forming the file name Order.xsl FileName: = FileName + ". Xsl"; // create XSLDoc document XSLDoc: = coDocXSL.Create; XSLDoc.LoadXML (FileName); // create XMLDoc document ResultDoc: = coDocResult.Create; // set synchronous processing mode ResultDoc.Set_async (false); // set parse check ResultDoc.validateOnParse: = true; // parsing XMLDoc using XSL template XMLDoc.transformNodeToObject (XSLDoc, ResultDoc); // the Str variable is assigned a text value // of the resulting document. Str: = ResultDoc.text; // find an element FNode: = r.SelectSingleNode ("// InvoiceNumber"); // and get the value of the element parm: = FNode.text; // close the request for access Query.Close; Query.Text: = Str; // assignment of parameter value Query.Params.AsString: = parm; // execute the request Query.ExecSQL; end;

The whole highlight of the parsing is the use of an XSL template, which is individually generated for each type of document. The result of parsing is a SQL query string. Subsequently, the execution of the generated SQL query string will make the necessary changes to the data in the DBMS.

The advantage of using parsing through a template is also that some data flexibility is obtained, and complete independence of the algorithm from the program code is obtained. Below is the text of the XSL template used to process an ORDER document:

INSERT into TABREG (FROM, TO, TYPEDOC, body) VALUES (" ", "", "") INSERT into GOODS (invoiceNumber, name, price, quality) VALUES (": num", " ", "", " ")

Explaining the above example, it should be noted that the use of a pair of tags is formal in nature, since after parsing, the resulting XML document must formally contain at least one node. The ResultDoc.text method assigns the text value of the ResultDoc obtained during parsing of the XML document. In this case, the value is everything that is framed by a pair of tags and, i.e. the SQL query we have generated.

Another feature of writing a program should be noted the possibility of using the SQL parameter : num. Using the parameter simplifies the text of the xsl template. The definition of the value of the corresponding elements of the nodes of the XML document is determined initially by the selection by the name of the corresponding node, for example:

XSL at a glance

The abbreviation XSL comes from eXtensible Stylesheet Language - a style sheet formatting language (XML data). As you can see from the header, eXtensible Stylesheet Language (XSL) is used to format XML data. By definition, the W3C XSL consists of two parts:

  • XSLT - XSL Transformation. The language used to transform or format (transform) XML documents. Thus, with the help of XSLT, we can get different cuts of a set of data and forms of data presentation.
  • Formatting elements. These elements include all the typographic elements of the data, after they have been processed with XSL. Used only for shaping HTML pages.

With the help of XSLT, we can select the data we need from an XML file, and arrange it in a form for presentation to the user. For example, in our case, we have transformed the XML data as SQL query... The classic use of XSL is usually formatting data in the form of HTML pages or, more rarely, in the form of RTF files.

XSL file describes a template, according to which the transformation of XML data will be performed. Returning to xsl templates, the following elements (directives) can be distinguished in XSLT:

XSL directives description
xsl: apply-templates A directive indicating the use of matching templates for the select attribute = "template name"
xsl: attribute creates an attribute tree and adds it to the output element, parameter name = "attribute name", namespace is the namespace URI (namespace prefix)
xsl: call-template calls a template, attribute name = "URI to template"
xsl: choose
xsl: when
xsl: otherwise
selection by condition xsl: when expr = "evaluation of expression on script",
language = "language-name"
test = "evaluated expression"
xsl: comment generates a comment in the output document
xsl: copy
xsl: copy-of
copies the current node to the output source or inserts a document fragment into a node where the select attribute = "source node name"
xsl: element creates an output element by name, attribute name = "element name", namespace = "uri namespace reference"
xsl: for-each reapplies the template to all nodes of the node list, the select attribute specifies the list of nodes
xsl: if condition check, specified by the test attribute as an expression
xsl: include includes external template, attribute href = "URI reference"
xsl: output specifies the output, the method attribute can be "xml", "html", or "text"
xsl: param specifies the value of the parameters, attribute name = "parameter name", select = "value"
xsl: processing-instruction creates a processing instruction, attribute name = "process instruction name"
xsl: sort sorts set of nodes, attributes select = "node name", data-type = data type ("text" | "number" | Qname), order = sort direction ("ascending" | "descending")
xsl: stylesheet defines an xsl template document, is the root element for XSLT
xsl: template defines an xsl-template, attribute name = "URI prefix to the template name", match = "an indication of the node to which the template is applied"
xsl: text generates text to the output stream, attribute disable-output-escaping = "yes" or "no", indicates the ability to generate ESC characters
xsl: value-of inserts the value of the selected node as text, attribute select = "pointer to node" from which the value is taken
xsl: variable specifies the value of variable boundaries, attribute name = "variable name", select = "calculation of variable value"
xsl: with-param applies parameter to template, attribute name = "parameter name", select = expression to evaluate the current context, default value "."

Conclusion

Finally, it should be noted that using the standard XML parser msxml.dll is not the only tool for parsing and creating XML documents. For example, to create XML documents effectively use the components TPageProduser and TableProduser... But, this article only emphasizes the breadth and applicability of the DOM model in practice.

The author will be very grateful for feedback on the relevance of the topic, general content, presentation style, as well as all other comments that will help to further improve the quality of writing a collection of articles and the release of a book covering the topic of the practical side of using XML documents in e-commerce. More detailed information about the practical side of the use of electronic documents can be found on the author's site www.eDocs.al.ru It is also planned to place the source texts and examples on the author's site.

XML is increasingly used to store information and exchange it between applications and Web sites. Many applications use this language as the base language for storing data, while others use it for exporting and importing XML data. So it’s time for developers to think about how XML data can be used in their own applications.

In this article, we will look at the XML Document Object Model (DOM) and Microsoft's implementation of the XML DOM.

The XML DOM is an object model that provides the developer with objects for loading and processing XML files. The object model consists of the following core objects: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap, and XMLDOMParseError. Each of these objects (except XMLDOMParseError) contains properties and methods that allow you to get information about the object, manipulate the object's values ​​and structure, and navigate the structure of an XML document.

Let's look at the main XML DOM objects and show some examples of their use in Borland Delphi.

Using XML DOM in Borland Delphi

In order to use Microsoft XML DOM in Delphi applications, you need to connect the appropriate type library to the project. To do this, we execute the command Project | Import Type Library and in the Import Type Library dialog box, select the Microsoft XML version 2.0 (Version 2.0) library, which is usually located in the Windows \ System \ MSXML.DLL file

After clicking the Create Unit button, the MSXML_TLB interface module will be created, which will allow us to use the XML DOM objects: DOMDocument, XMLDocument, XMLHTTPRequest and a number of others, implemented in the MSXML.DLL library. The reference to the MSXML_TLB module must be in the Uses list.

XML DOM device

The Document Object Model represents an XML document in a tree structure of branches. XML DOM APIs allow applications to navigate the document tree and manipulate its branches. Each branch can have a specific type (DOMNodeType), according to which the parent and child branches are determined. Most XML documents contain branches of type element, attribute, and text. Attributes are a special kind of branch and are not child branches. Special methods provided by XML DOM objects are used to manipulate attributes.

In addition to implementing World Wide Web Consortium (W3C) recommended interfaces, the Microsoft XML DOM contains methods that support XSL, XSL Patterns, Namespaces, and data types. For example, the SelectNodes method allows you to use XSL Pattern Syntax to find branches in a specific context, and the TransformNode method supports using XSL to perform transformations.

Test XML Document

As an example XML document, let's take a music CD-ROM directory, which has the following structure:

Empire burlesque Bob dylan USA Columbia 10.90 1985 Hide your heart Bonnie tylor UK CBS Records 9.90 1988 ... Unchain my heart Joe cocker USA EMI 8.20 1987

We are now ready to start looking at the XML DOM object model, starting with the XMLDOMDocument object.

XML Document - XMLDOMDocument Object

Working with an XML document begins with loading it. To do this, we use the Load method, which has only one parameter that specifies the URL of the loaded document. When loading files from a local disk, only the full file name is specified (the file: /// protocol can be omitted in this case). If the XML document is stored as a string, use the LoadXML method to load the document.

The Async property is used to control how the document is loaded (synchronous or asynchronous). By default, this property is set to True, indicating that the document is loaded asynchronously and control is returned to the application before the document is fully loaded. Otherwise, the document loads synchronously, and then you have to check the value of the ReadyState property to see if the document has loaded or not. You can also create an event handler for the OnReadyStateChange event that will take control when the value of the ReadyState property changes.

The following shows how to load an XML document using the Load method:

Uses ... MSXML_TLB ... procedure TForm1.Button1Click (Sender: TObject); var XMLDoc: IXMLDOMDocument; begin XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // // This is where the code that manipulates // the XML document and its branches // XMLDoc: = Nil; end;

After the document is loaded, we can access its properties. So, the NodeName property will contain the #document value, the NodeTypeString property will contain the document value, and the URL property will contain the file: /// C: /DATA/DATA.xml value.

Error handling

Of particular interest are properties related to document processing upon loading. For example, the ParseError property returns an XMLDOMParseError object containing information about an error that occurred while processing the document.

To write an error handler, you can add the following code:

Var XMLError: IXMLDOMParseError; ... XMLDoc.Load (‘C: \ DATA \ DATA.xml’); XMLError: = XMLDoc.ParseError; If XMLError.ErrorCode<>0 Then // // Here we handle the error // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: = Nil;

To find out what information is returned in case of an error, change the following directory entry:

Empire burlesque Bob dylan USA Columbia 10.90 1985

removing the closing element on the second line:</p><p> <CD> <TITLE>Empire burlesque <ARTIST>Bob dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> </p><p>Now let's write some code that returns the property values ​​of the XMLDOMParseError object:</p><p>XMLError: = XMLDoc.ParseError; If XMLError.ErrorCode<>0 Then With XMLError, Memo1.Lines do begin Add (‘File:’ + URL); Add (‘Code:’ + IntToStr (ErrorCode)); Add (‘Error:’ + Reason); Add (‘Text:’ + SrcText); Add (‘Line:’ + IntToStr (Line)); Add (‘Position:’ + IntToStr (LinePos)); end Else Memo1.Lines.Add (XMLDoc.XML); End;</p><p>and execute our application. As a result, we get the following information about the error.</p> <p>As you can see from the above example, the information returned by the XMLDOMParseError object is quite enough to localize the error and understand the cause of its occurrence.</p> <p>Now we will restore the closing element <TITLE>in our document and continue our discussion of the XML DOM.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2>Accessing the document tree</h2> <p>To access the document tree, you can either get the root element and then iterate over its child branches, or find a specific branch. In the first case, we get the root element through the DocumentElement property, which returns an object of type XMLDOMNode. The following shows how to use the DocumentElement property to get the contents of each child element:</p><p>Var Node: IXMLDOMNode; Root: IXMLDOMElement; I: Integer; ... Root: = XMLDoc.DocumentElement; For I: = 0 to Root.ChildNodes.Length-1 do Begin Node: = Root.ChildNodes.Item [I]; Memo1.Lines.Add (Node.Text); End;</p><p>For our XML document, we get the following text.</p> <p>If we are interested in a specific branch or a branch below the first child branch, we can use either the NodeFromID method or the GetElementByTagName method of the XMLDOMDocument object.</p> <p>The NodeFromID method requires a unique identifier as defined in the XML Schema or Document Type Definition (DTD) and returns a branch with that identifier.</p> <p>The GetElementByTagName method requires a string with a specific element (tag) and returns all branches with this element. Here's how to use this method to find all the artists in our CD-ROM directory:</p><p>Nodes: IXMLDOMNodeList; Node: IXMLDOMNode; ... Nodes: = XMLDoc.GetElementsByTagName (‘ARTIST’); For I: = 0 to Nodes.Length-1 do Begin Node: = Nodes.Item [I]; Memo1.Lines.Add (Node.Text); End;</p><p>For our XML document, we will get the following text</p> <p>Note that the SelectNodes method of the XMLDOMNode object provides a more flexible way to access document branches. But more on that below.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2>Document Branch - XMLDOMNode Object</h2> <p>The XMLDOMNode object represents a document branch. We already encountered this object when we got the root element of the document:</p><p>Root: = XMLDoc.DocumentElement;</p><p>To obtain information about a branch of an XML document, you can use the properties of the XMLDOMNode object (Table 1).</p> <p>To access the data stored in a branch, it is common to use either the NodeValue property (available for attributes, text branches, comments, processing instructions, and CDATA sections), or the Text property, which returns the text content of the branch, or the NodeTypedValue property. The latter, however, can only be used for branches with typed items.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h3>Navigating the document tree</h3> <p>The XMLDOMNode object provides many ways to navigate the document tree. For example, to access the parent branch, use the ParentNode property (XMLDOMNode type), access the child branches through the ChildNodes properties (XMLDOMNodeList type), FirstChild and LastChild (XMLDOMNode type), etc. The OwnerDocument property returns an XMLDOMDocument object that identifies the XML document itself. The properties listed above make it easy to navigate the document tree.</p> <p>Now let's loop through all the branches of the XML document:</p><p>Root: = XMLDoc.DocumentElement; For I: = 0 to Root.ChildNodes.Length-1 do Begin Node: = Root.ChildNodes.Item [I]; If Node.HasChildNodes Then GetChilds (Node, 0); End;</p><p>As noted above, the SelectNodes of the XMLDOMNode object provides a more flexible way to access document branches. In addition, there is a SelectSingleNode method that returns only the first branch of the document. Both of these methods allow you to define XSL templates for branch searches.</p> <p>Let's look at the process of using the SelectNodes method to fetch all branches that have a CD branch and a PRICE sub-branch:</p><p>Root: = XMLDoc.DocumentElement; Nodes: = Root.SelectNodes (‘CD / PRICE’);</p><p>All PRICE sub-branches of the CD branch will be placed in the Nodes collection. We'll come back to discussing XSL templates a bit later.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h3>Manipulating child branches</h3> <p>To manipulate child branches, we can use the methods of the XMLDOMNode object (Table 2).</p> <p>In order to completely delete the record about the first disk, you need to run the following code:</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Node: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // Get the root element Root: = XMLDoc.DocumentElement; Node: = Root; // Remove the first child branch Node.RemoveChild (Node.FirstChild);</p><p>Note that in this example we are deleting the first child branch. How to remove the first element of the first child branch is shown below:</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Node: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml’); // Get the root element Root: = XMLDoc.DocumentElement; // and the first child branch Node: = Root.FirstChild; // Remove the first child branch Node.RemoveChild (Node.FirstChild);</p><p>In the above example, we deleted not the first branch <CD>…</CD> and the first element of the branch is <TITLE>….

Now let's add a new branch. Below is the code showing how to add a new music CD-ROM entry:

Var NewNode: IXMLDOMNode; Child: IXMLDOMNode; ... // Create a new branch - NewNode: = XMLDoc.CreateNode (1, ‘CD’, ‘’); // Add an element Child: = XMLDoc.CreateNode (1, ‘TITLE’, ‘’); // Add an element NewNode.AppendChild (Child); // And set its value Child.Text: = ‘Pink Floyd’; // Add an element <ARTIST>Child: = XMLDoc.CreateNode (1, ‘ARTIST’, ‘’); // Add an element NewNode.AppendChild (Child); // And set its value Child.Text: = ‘Division Bell’; // Add an element <COUNTRY>Child: = XMLDoc.CreateNode (1, ‘COUNTRY’, ‘’); // Add an element NewNode.AppendChild (Child); // And set its value Child.Text: = ‘UK’; // Add an element <COMPANY>Child: = XMLDoc.CreateNode (1, ‘COMPANY’, ‘’); // Add an element NewNode.AppendChild (Child); // And set its value Child.Text: = ‘EMI Records Ltd.’; // Add an element <PRICE>Child: = XMLDoc.CreateNode (1, ‘PRICE’, ‘’); // Add an element NewNode.AppendChild (Child); // And set its value Child.Text: = '11 .99 "; // Add an element <YEAR>Child: = XMLDoc.CreateNode (1, ‘YEAR’, ‘’); // Add an element NewNode.AppendChild (Child); // And set its value Child.Text: = ‘1994’; // And add a branch Root.AppendChild (NewNode); ...</p><p>The above code shows the following steps to add a new branch:</p> <ul><li>Creating a new branch using the CreateNode method: <ul><li>creating an element using the CreateNode method;</li> <li>adding an element to a branch using the AppendChild method;</li> <li>setting the value of an element through the Text property;</li> <li>… Repeat for all elements.</li> </ul></li> <li>Adding a new branch to the document using the AppendChild method.</li> </ul><p>Recall that the AppendChild method adds a branch to the end of the tree. In order to add a branch to a specific place in the tree, you need to use the InsertBefore method.</p> <h2>Branch set - XMLDOMNodeList object</h2> <p>The XMLNodeList object contains a list of branches, which can be built using the SelectNodes or GetElementsByTagName methods, and also obtained from the ChildNodes property.</p> <p>We have already discussed the use of this object in the example provided in the section "Navigating the document tree". Here are some theoretical comments.</p> <p>The number of branches in the list can be obtained as the value of the Length property. The branches are indexed from 0 to Length-1, and each individual branch is accessible through the corresponding indexed item in the Item array.</p> <p>Navigating through the list of branches can also be done using the NextNode method, which returns the next branch in the list, or Nil if the current branch is the last. To return to the top of the list, call the Reset method.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2>Create and save documents</h2> <p>So, we've covered how you can add branches and elements to existing XML documents. Now let's create an XML document on the fly. First of all, remember that a document can be loaded not only from a URL, but also from a regular string. The following shows how to create a root element, which can then be used to dynamically build the rest of the elements (which we already covered in the section "Manipulating child branches"):</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Node: IXMLDOMNode; S: WideString; ... S: = ‘ <CATALOG></CATALOG>'; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.LoadXML (S); Root: = XMLDoc.DocumentElement; Node: = XMLDoc.CreateNode (1, ‘CD’, ‘’); Root.AppendChild (Node); Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: = Nil;</p><p>After building the XML document, save it to a file using the Save method. For example:</p> <p>XMLDoc.Save (‘C: \ DATA \ NEWCD.XML’);</p> <p>In addition to saving to a file, the Save method allows you to save an XML document in a new XMLDOMDocument object. In this case, the document is fully processed and, as a result, its structure and syntax are checked. Here's how to save a document to another object:</p><p>Procedure TForm1.Button2Click (Sender: TObject); var XMLDoc2: IXMLDOMDocument; begin XMLDoc2: = CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: = Nil; end;</p><p>In conclusion, the Save method also allows you to save the XML document to other COM objects that support the IStream, IPersistStream, or IPersistStreamInit interfaces.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2>Using XSL Templates</h2> <p>When discussing the SelectNodes method of the XMLDOMNode object, we mentioned that it provides a more flexible way to access document branches. The flexibility is that you can specify an XSL template as the criteria for selecting branches. Such templates provide a powerful mechanism for finding information in XML documents. For example, to get a list of all the music CD-ROM titles in our directory, you can run the following query:</p><p>To find out which artists' discs are released in the USA, the request is formed as follows:</p><p>Nodes: = Root.SelectNodes (‘CD / ARTIST’);</p><p>Here's how to find the first drive in a directory:</p><p>Nodes: = Root.SelectNodes (‘CD / TITLE’);</p><p>And last:</p><p>Nodes: = Root.SelectNodes (‘CD / TITLE’);</p><p>To find Bob Dylan's disks, you can run the following query:</p><p>Nodes: = Root.SelectNodes (‘CD [$ any $ ARTIST =” Bob Dylan ”] / TITLE’);</p><p>and to get a list of disks made after 1985, we run the following query:</p><p>Nodes: = Root.SelectNodes (‘CD / TITLE’);</p><p>A more detailed discussion of XSL syntax requires a separate publication. To intrigue readers and encourage further research, I will give just one small example of the possible use of XSL. Let's say we need to convert our directory to a regular HTML table. Using the traditional methods, we must iterate over all the branches of the tree and for each received element form the corresponding tags <TD>…</TD>.</p> <p>Using XSL, we simply create a template (or stylesheet) that specifies what and how to transform. Then we overlay this template on our catalog - and that's it: we have the text of an XSL template that transforms the catalog into a table (Listing 2).</p> <p>The code to overlay an XSL template on our directory looks like this:</p><p>Procedure TForm1.Button2Click (Sender: TObject); var XSLDoc: IXMLDOMDocument; begin XSLDoc: = CoDOMDocument.Create; XSLDoc.Load (‘C: \ DATA \ DATA.xsl’); Memo2.Text: = XMLDoc.TransformNode (XSLDoc); XSLDoc: = Nil; end;</p><p>Concluding our discussion of XSL, it should be said that at present this language is actively used for transformation between various XML documents, as well as for formatting documents.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2>Conclusion</h2> <p>For obvious reasons, it is impossible to cover all Microsoft XML DOM objects and provide examples of their use in one article. Here we have just touched on the basic issues of using XML DOM in applications. Table 3 shows all the objects implemented in the Microsoft XML DOM.</p> <p>ComputerPress 12 "2000</p> <script>document.write("<img style='display:none;' src='//counter.yadro.ru/hit;artfast_after?t44.1;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";h"+escape(document.title.substring(0,150))+ ";"+Math.random()+ "border='0' width='1' height='1' loading=lazy loading=lazy>");</script> </div> </div> </div> </div> <aside class="col-lg-4 col-md-12 col-md-offset-4 col-lg-offset-0" id="right"> <div> </div> <br/> <div> </div> <br/> <div> </div> <br/> <div> </div> <br/> </aside> </div> </div> </div> <div class="popup" id="share"> <div class="perfect-scroll" style="text-align: center"> <div style="margin-bottom: 20px"> <strong>The download will start now ...</strong> <br>Don't forget to share material <br>on social networks with your <br>colleagues</div> <div> <div class="ya-share2" data-services="vkontakte,facebook,odnoklassniki,moimir,gplus" data-counter=""></div> </div> </div> <div class="close-pop pull-right"> <svg width="10px" height="10px" viewBox="0 0 10 10"> <path fillrule="evenodd" d="M 6.41 5C 6.41 5 9.24 7.83 9.24 7.83 9.63 8.22 9.63 8.85 9.24 9.24 8.85 9.63 8.22 9.63 7.83 9.24 7.83 9.24 5 6.41 5 6.41 5 6.41 2.17 9.24 2.17 9.24 1.78 9.63 1.15 9.63 0.76 9.24 0.37 8.85 0.37 8.22 0.76 7.83 0.76 7.83 3.59 5 3.59 5 3.59 5 0.76 2.17 0.76 2.17 0.37 1.78 0.37 1.15 0.76 0.76 1.15 0.37 1.78 0.37 2.17 0.76 2.17 0.76 5 3.58 5 3.58 5 3.58 7.83 0.76 7.83 0.76 8.22 0.37 8.85 0.37 9.24 0.76 9.63 1.15 9.63 1.78 9.24 2.17 9.24 2.17 6.41 5 6.41 5Z"></path> </svg> </div> </div> <section id="views"> <div class="container"> </div> </section> <script type="text/javascript"> $(document).ready( function () { $('.kursiv').readmore({ speed: 75, maxHeight: 84, heightMargin: 16, moreLink: '<a href="#"><span>Показать полностью</span>', lessLink: '<a href="#"><span>Скрыть</span></a>', } ); } ); </script> <style> div.kursiv { margin-bottom: 0; } #razrabotka { margin-top: 30px; } .readmore-js-toggle { font-style: italic; color: #999; display: inline; margin-right: 10px; font-size: 14px; cursor: pointer; border-bottom: 1px dotted #e6e6e6; } </style></section> <footer> <div class="container"> <div class="row"> <div class="col-xs-16 col-sm-4 col-md-3"> <p>© 2021, mkr-novo2.ru, Internet. Education. Programs. Firmware. Installation and configuration. Navigators</p> <div class="social"> <a target="_blank" href=""> <svg width="32px" height="19px" viewBox="0 0 32 19"> <path fillRule="evenodd" d="M 15.36 18.01C 15.36 18.01 17.24 18.01 17.24 18.01 17.24 18.01 17.81 17.94 18.1 17.64 18.36 17.37 18.35 16.85 18.35 16.85 18.35 16.85 18.32 14.41 19.49 14.05 20.64 13.7 22.12 16.4 23.69 17.45 24.87 18.23 25.77 18.06 25.77 18.06 25.77 18.06 29.97 18.01 29.97 18.01 29.97 18.01 32.16 17.87 31.12 16.21 31.03 16.07 30.51 14.97 28 12.72 25.37 10.35 25.72 10.74 28.89 6.65 30.82 4.16 31.59 2.65 31.35 2 31.12 1.38 29.7 1.54 29.7 1.54 29.7 1.54 24.98 1.57 24.98 1.57 24.98 1.57 24.63 1.52 24.37 1.67 24.12 1.82 23.95 2.16 23.95 2.16 23.95 2.16 23.21 4.09 22.21 5.72 20.11 9.18 19.27 9.36 18.92 9.15 18.12 8.65 18.32 7.14 18.32 6.07 18.32 2.72 18.85 1.32 17.3 0.96 16.79 0.84 16.41 0.76 15.1 0.75 13.41 0.73 11.99 0.76 11.18 1.14 10.64 1.39 10.23 1.96 10.48 1.99 10.79 2.03 11.5 2.18 11.88 2.67 12.36 3.31 12.34 4.74 12.34 4.74 12.34 4.74 12.62 8.68 11.69 9.17 11.06 9.5 10.18 8.82 8.31 5.68 7.35 4.08 6.62 2.3 6.62 2.3 6.62 2.3 6.48 1.97 6.23 1.8 5.93 1.58 5.51 1.51 5.51 1.51 5.51 1.51 1.02 1.54 1.02 1.54 1.02 1.54 0.35 1.56 0.1 1.84-0.12 2.09 0.08 2.62 0.08 2.62 0.08 2.62 3.6 10.57 7.57 14.57 11.22 18.25 15.36 18.01 15.36 18.01 15.36 18.01 15.36 18.01 15.36 18.01Z"/> </svg> </a> <a target="_blank" href=""> <svg viewBox="0 0 25 25" width="25px" height="25px"> <path class="st0" d="M12.5,12.7c3.2,0,5.8-2.6,5.8-5.8c0-3.2-2.6-5.8-5.8-5.8C9.3,1,6.7,3.6,6.7,6.8C6.7,10,9.3,12.7,12.5,12.7z M12.5,3.9c1.6,0,2.9,1.3,2.9,2.9c0,1.6-1.3,2.9-2.9,2.9c-1.6,0-2.9-1.3-2.9-2.9C9.6,5.2,10.9,3.9,12.5,3.9z M19.2,13.4 c-0.3-0.7-1.2-1.2-2.5-0.3c-1.6,1.3-4.3,1.3-4.3,1.3s-2.6,0-4.3-1.3c-1.2-1-2.1-0.4-2.5,0.3c-0.6,1.2,0.1,1.7,1.5,2.7 c1.3,0.8,3,1.1,4.1,1.2l-0.9,0.9c-1.3,1.3-2.6,2.6-3.4,3.4c-0.5,0.5-0.5,1.4,0,1.9l0.2,0.2c0.5,0.5,1.4,0.5,1.9,0l3.4-3.4 c1.3,1.3,2.6,2.6,3.4,3.4c0.5,0.5,1.4,0.5,1.9,0l0.2-0.2c0.5-0.5,0.5-1.4,0-1.9l-3.4-3.4l-0.9-0.9c1.1-0.1,2.8-0.4,4.1-1.2 C19.2,15.1,19.8,14.5,19.2,13.4z"/> </svg> </a> <a target="_blank" href="https://facebook.com/"> <svg width="26px" height="25px" viewBox="0 0 26 25"> <path fillRule="evenodd" d="M 24.33-0C 24.33-0 1.96-0 1.96-0 1.19-0 0.57 0.62 0.57 1.38 0.57 1.38 0.57 23.62 0.57 23.62 0.57 24.38 1.19 25 1.96 25 1.96 25 14 25 14 25 14 25 14 15.32 14 15.32 14 15.32 10.72 15.32 10.72 15.32 10.72 15.32 10.72 11.54 10.72 11.54 10.72 11.54 14 11.54 14 11.54 14 11.54 14 8.76 14 8.76 14 5.53 15.98 3.77 18.88 3.77 20.27 3.77 21.46 3.88 21.81 3.92 21.81 3.92 21.81 7.3 21.81 7.3 21.81 7.3 19.8 7.3 19.8 7.3 18.22 7.3 17.92 8.04 17.92 9.13 17.92 9.13 17.92 11.54 17.92 11.54 17.92 11.54 21.68 11.54 21.68 11.54 21.68 11.54 21.19 15.32 21.19 15.32 21.19 15.32 17.92 15.32 17.92 15.32 17.92 15.32 17.92 25 17.92 25 17.92 25 24.33 25 24.33 25 25.09 25 25.71 24.38 25.71 23.62 25.71 23.62 25.71 1.38 25.71 1.38 25.71 0.62 25.09-0 24.33-0Z"/> </svg> </a> <a target="_blank" href="https://youtube.com/"> <svg width="26px" height="19px" viewBox="0 0 26 19"> <path fillRule="evenodd" d="M 25.75 14.46C 25.75 14.46 25.5 16.18 24.75 16.93 23.79 17.92 22.72 17.93 22.23 17.99 18.71 18.24 13.43 18.25 13.43 18.25 13.43 18.25 6.89 18.19 4.88 18 4.32 17.89 3.06 17.92 2.11 16.93 1.35 16.18 1.11 14.46 1.11 14.46 1.11 14.46 0.86 12.45 0.86 10.44 0.86 10.44 0.86 8.55 0.86 8.55 0.86 6.54 1.11 4.52 1.11 4.52 1.11 4.52 1.35 2.81 2.11 2.05 3.06 1.06 4.14 1.06 4.63 1 8.15 0.75 13.42 0.75 13.42 0.75 13.42 0.75 13.43 0.75 13.43 0.75 13.43 0.75 18.71 0.75 22.23 1 22.72 1.06 23.79 1.06 24.75 2.05 25.5 2.81 25.75 4.52 25.75 4.52 25.75 4.52 26 6.54 26 8.55 26 8.55 26 10.44 26 10.44 26 12.45 25.75 14.46 25.75 14.46ZM 10.83 5.73C 10.83 5.73 10.83 12.72 10.83 12.72 10.83 12.72 17.62 9.24 17.62 9.24 17.62 9.24 10.83 5.73 10.83 5.73Z"/> </svg> </a> </div> </div> <div class="col-lg-2 col-sm-4 col-xs-16 links"> <h4>mkr-novo2.ru</h4> <a href="https://mkr-novo2.ru/en/category/internet/">Internet</a> <a href="https://mkr-novo2.ru/en/category/multimedia/">Multimedia</a> <a href="https://mkr-novo2.ru/en/category/navigation/">Navigators</a> <a href="https://mkr-novo2.ru/en/category/education/">Education</a> <a href="https://mkr-novo2.ru/en/category/at/">ON</a> <a href="https://mkr-novo2.ru/en/category/problems/">Problems</a> </div> <div class="col-lg-2 col-sm-3 col-xs-16 links"> <h4>about the project</h4> <a href="">Feedback</a> <a href="">About the site</a> </div> <div class="col-lg-5 col-sm-1 col-xs-16 links"></div> <div class="col-lg-4 col-sm-5 col-xs-16 links"> </div> </div> <div class="row v-center"> <div class="col-md-8 col-xs-16"> <a data-fancybox data-type="iframe" data-src="">Contacts</a> </div> <div class="col-md-8 col-xs-16"> <div class="share pull-right"> <script type="text/javascript" src="//yastatic.net/es5-shims/0.0.2/es5-shims.min.js" charset="utf-8"></script> <script type="text/javascript" src="//yastatic.net/share2/share.js" charset="utf-8"></script> <div class="ya-share2" data-services="vkontakte,facebook,odnoklassniki,moimir,gplus" data-counter=""></div> </div> </div> </div> </div> </footer> <a href="#bot" id="to-top"> <svg width="50px" height="50px" viewBox="0 0 50 50"> <circle cx="25.00" cy="25.00" r="25.00" fill="rgb(0,0,0)" opacity="0.37"/> <path fillRule="evenodd" d="M 33.94 24.46C 33.94 24.46 25.89 16.3 25.89 16.3 25.32 15.73 24.41 15.73 23.84 16.3 23.84 16.3 15.79 24.46 15.79 24.46 14.88 25.38 15.52 26.97 16.81 26.97 16.81 26.97 20.43 26.97 20.43 26.97 21.23 26.97 21.88 27.62 21.88 28.43 21.88 28.43 21.88 32.51 21.88 32.51 21.88 33.71 22.83 34.68 24.01 34.68 24.01 34.68 25.72 34.68 25.72 34.68 26.9 34.68 27.86 33.71 27.86 32.51 27.86 32.51 27.86 28.43 27.86 28.43 27.86 27.62 28.5 26.97 29.31 26.97 29.31 26.97 32.92 26.97 32.92 26.97 34.21 26.97 34.85 25.38 33.94 24.46Z" fill="rgb(241,241,241)"/> </svg> </a> <div class="overlay"></div> <div class="popup" id="password"> <div class="perfect-scroll"> <h2>Password recovery <div class="close-pop pull-right"> <svg width="10px" height="10px" viewBox="0 0 10 10"> <path fillRule="evenodd" d="M 6.41 5C 6.41 5 9.24 7.83 9.24 7.83 9.63 8.22 9.63 8.85 9.24 9.24 8.85 9.63 8.22 9.63 7.83 9.24 7.83 9.24 5 6.41 5 6.41 5 6.41 2.17 9.24 2.17 9.24 1.78 9.63 1.15 9.63 0.76 9.24 0.37 8.85 0.37 8.22 0.76 7.83 0.76 7.83 3.59 5 3.59 5 3.59 5 0.76 2.17 0.76 2.17 0.37 1.78 0.37 1.15 0.76 0.76 1.15 0.37 1.78 0.37 2.17 0.76 2.17 0.76 5 3.58 5 3.58 5 3.58 7.83 0.76 7.83 0.76 8.22 0.37 8.85 0.37 9.24 0.76 9.63 1.15 9.63 1.78 9.24 2.17 9.24 2.17 6.41 5 6.41 5Z"/> </svg> </div> </h2> <div class="recover-success"> <form action="/recovery/request" data-method="post" method="post" class="recover_form"> <p>Enter your email to recover your password!</p> <div class="input-wrp"> <input name="email" type="text" placeholder="Enter your e-mail"> </div> <input type="submit" data-disable-with="Отправить..." class="btn green" value="send"> </form> </div> <div class="auth-form_error" style="padding-top: 10px"></div> </div> </div> <script> $('.user.one').click(function (e, ob) { $('.user').removeClass('active-user'); $('.user.one').addClass('active-user'); $('#user_type').val('1'); e.stopPropagation(); } ); $('.user.two').click(function (e, ob) { $('.user').removeClass('active-user'); $('.user.two').addClass('active-user'); $('#user_type').val('2'); e.stopPropagation(); } ); $('.user.three').click(function (e, ob) { $('.user').removeClass('active-user'); $('.user.three').addClass('active-user'); $('#user_type').val('3'); e.stopPropagation(); } ); function clearErrors() { $('.auth-form_error').each(function () { $(this).html(''); } ); } $('body').on('click', '.open-login-form', function (e) { $('#register, .overlay').removeClass('visible-pop'); $('#login, .overlay').addClass('visible-pop'); e.preventDefault(); } ); $('body').on('click', '.open-pass-form', function (e) { $('#register, .overlay').removeClass('visible-pop'); $('#password, .overlay').addClass('visible-pop'); e.preventDefault(); } ); $('.login_form') .on('ajax:beforeSend', function (event, xhr, settings) { clearErrors(); } ) .on('ajax:complete', function (event, xhr, status) { } ) .on('ajax:success', function (event, data, status, xhr) { if (data.status == 0) { $('.auth-form_error').html(data.text + '<br>'); } else { $('.open-register').html(data.text); var delay = 1000; window.location.href = url = window.location.href + "?login=ok"; location.replace(url); setTimeout('window.location.reload(true);', delay); } } ).on('ajax:error', function (event, xhr, status, error) { } ); $('.recover_form') .on('ajax:beforeSend', function (event, xhr, settings) { clearErrors(); } ) .on('ajax:complete', function (event, xhr, status) { } ) .on('ajax:success', function (event, data, status, xhr) { console.log(data); if (data.status == 0) { $('.auth-form_error').html(data.text + '<br>'); } else { $('.recover-success').html('<div class="success" >' + data.text + '</div>'); } } ).on('ajax:error', function (event, xhr, status, error) { } ); $('.registration_form') .on('ajax:beforeSend', function (event, xhr, settings) { var emailError = $('#emailError'); var passwordError = $('#passwordError'); var passwordVerify = $('#passwordVerifyError'); var userTypeError = $('#userTypeError'); var emailExist = $('#emailExist'); emailError.html(''); passwordError.html(''); passwordVerify.html(''); userTypeError.html(''); emailExist.hide(); } ) .on('ajax:complete', function (event, xhr, status) { } ).on('ajax:success', function (event, data, status, xhr) { // insert the failure message inside the "#account_settings" element //console.log(data); if (data.status == 0) { //$('.reg-info').html('<div class="error">' + data.text + '</div>'); if (data.text.email) { var emailError = $('#emailError'); var emailExist = $('#emailExist'); console.log(data.text.email); if (data.text.email == 'Найдена совпадающая со значением запись') { console.log('alert'); emailExist.show(); } else { emailError.html('<i class="icon-error"></i><div class="error_note_wrapper">' + '<div class="error_note">' + '<span class="error_note_text">' + data.text.email + '</span></div></div>'); } } if (data.text.password) { var passwordError = $('#passwordError'); console.log(data.text.password); passwordError.html('<i class="icon-error"></i><div class="error_note_wrapper">' + '<div class="error_note">' + '<span class="error_note_text">' + data.text.password + '</span></div></div>'); } if (data.text.passwordVerify) { var passwordVerify = $('#passwordVerifyError'); console.log(data.text.passwordVerify); passwordVerify.html('<i class="icon-error"></i><div class="error_note_wrapper">' + '<div class="error_note">' + '<span class="error_note_text">' + data.text.passwordVerify + '</span></div></div>'); } if (data.text.captcha) { var captcha = $('#captchaError'); console.log(data.text.captcha); captcha.html('<i class="icon-error"></i><div class="error_note_wrapper">' + '<div class="error_note">' + '<span class="error_note_text">' + data.text.captcha + '</span></div></div>'); } if (data.text.userType) { var user_type = $('#userTypeError'); console.log(data.text.userType); user_type.html('<i class="icon-error"></i><div class="error_note_wrapper">' + '<div class="error_note">' + '<span class="error_note_text">' + data.text.userType + '</span></div></div>'); } } else { $('.reg-success').html(data.text); var delay = 2000; window.location.href = url = window.location.href + "?reg=ok"; location.replace(url); setTimeout('window.location.reload(true);', delay); } } ).on('ajax:error', function (event, xhr, status, error) { } ); </script> <div class="popup" id="premium-pop"> </div> <link rel="stylesheet" href="/videouroki/res/lightslider/lightslider.min.css"> <link rel="stylesheet" href="/videouroki/res/perfectScrollbar/perfect-scrollbar.css"> <link rel="stylesheet" href="/videouroki/assets/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/assets/vendor/fancybox/jquery.fancybox.min.css"> <script src="/videouroki/res/perfectScrollbar/perfect-scrollbar.jquery.min.js"></script> <script src="/js/rails.js"></script> <script src="/videouroki/res/lightslider/lightslider.min.js"></script> <script src="/videouroki/res/jquery.validate.min.js"></script> <script src="/videouroki/res/autosize-master/autosize.min.js"></script> <script src="/videouroki/js/tabs.js"></script> <script src="/videouroki/js/select.js"></script> <script src="/videouroki/js/global.js?2109"></script> <script src="/videouroki/js/views.js"></script> <script src="/videouroki/plugin/notify/notify.min.js"></script> <script src="/videouroki/plugin/notify/notify-metro.js"></script> <script src="/videouroki/js/lazyload.min.js"></script> <script src="/assets/vendor/fancybox/jquery.fancybox.min.js"></script> <script type="text/javascript"> $(document).ready( function () { // new LazyLoad(); } ) </script> <!--[if gte IE 9]><script type="text/javascript" src="/videouroki/assets/ckeditor-mini/ckeditor.js"></script><![endif]--> <script type="text/javascript" src="/videouroki/js/readmore.js"></script></body> </html>