XML (Extensible Markup Language)


XML

The language XML is simple language than can be used to store and exchange information. As XML is a standard language, it is possible to exchange information between two computers with a different operating system, or between two programs written in different languages. Thus, XML defines an standard to store and exchange data.

XML File

XML can be used to create an XML file. An XML file is a text file with extension .xml that follows some simple rules. An xml file can be used to store and exchange information. For instance, a company may provide an XML file to report taxes. The first line of an XML file must be: <?xml version="1.0" encoding="utf-8"?>. XML data can be created by concatenating text while replacing some special characters. XML data must be converted to UTF-8 before saving to disk or sending over the Internet.

XML on the Internet

XML is typically using exchange over the Internet to perform operations and transactions.
XML es típicamente usado para intercambiar información en la Internet para hacer operaciones y transacciones.

Problem 1
Use notepad to create an XML file called hello.xml to store a message. Be sure to save the file as hello.xml with encoding UTF8. By default notepad will save the file as helo.xml.txt, so you must select the option: All Files (*.*) as shown. Observe that an XML file is composed of tags. These tags are declared using the symbols: > and <. HTML uses standard tags, on the other hand, XML allows the user to define his own tags. For instance in the file helo.xml, the tag <message> was defined for us.

Save

HelloNotepad

Tip
You may use several programs to open an XML file. Microsoft Visual Studio can be used to open an edit an XML file. If you drag and drop the hello.xml file over Microsoft Internet Explorer, you will be able to see the XML file as shown below.

HelloIe

Problem 2
Using Microsoft Visual Studio open the hello.xml file, then edit the file to create an error in the closing tag as shown. Microsoft Visual Studio will indicate the error.

HelloError

Problem 3
Create an XML file called people.xml to store the name and personal information of your friends. You may create the file using Microsoft Visual Studio, Notepad or your favorite editor.

PeopleXml

Root Node

An XML file is structured in nodes. The main node is called Root Node. In the people.xml file, the root node is the <people> node as shown below.

RootNode

Child Nodes

The main node may have several child nodes. In the people.xml file, the <friend> nodes are child nodes of the root node <people> as shown below.

ChildNodes

Elements

A node may have several elements. For instance, in the people.xml file the tags: first_name, last_name, age, email, phone and sex are elements of the friend node as shown below.

Elements

Special Symbols

As tags are defined using the symbols: > and <. These characters cannot be used for other purposes. XML has five reserved characters: >, < &, ' and ". In other to use these characters an special sequence must be used as shown.

  Special Symbol    Meaning  
> &gt;
< &lt;
& &amp;
' &apos;
" &quot;

Problem 4
Create an XML file called equation to display the equation shown.

EquationVs

EquationIe

Comments

XML allows introducing comments to an XML file to make the file easy to understand. As in other languages, comments provide information that is not obvious. Comments in HTML and XML use the same format.

Problem 5
Edit the people.xml file to introduce some comments as shown.

PeopleComment

Attributes

XML allows adding one or more attributes to each tag. An attribute is declared inside the tag as shown in the next problem. In this case, the Social Security Number (SSN) is an attribute of friend. In Mexico a RFC can be an attribute. Inside the University a student ID (NUA) can be an attribute.

Tip
Use attributes to identify a child node, and use node elements to include properties of the child node. Thus, an attribute identifies a child node, while an element provides more information about then node.

Problem 6
Edit the people.xml file to add his or her Social Security Number.

PeopleAttribute

Including Text

When including too much text into an XML file, the reserved characters must be replaced before pasting or writing the text. It is possible to paste a text block without replacing the reserved characters using a CDATA block as shown in the next problem.

Problem 7
Create the file program.xml to include a block code as shown.

Program

Problem 8
Create a Dialog application called ReadingXml using Wintempla. Using Wintempla insert a textbox called tbxOutput. Set the multiline property of the textbox.

tbxOutput

Step A
Open and edit the stdafx.h file of your project by including the msxml.h file as shown.

stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
. . .
#include "msxml.h"


Step B
Copy the people.xml file to the folder of your project.

PeopleCopy

Step C
Edit the ReadingXml.cpp file as shown.

ReadingXml.cpp
#include "stdafx.h" //________________________________________ ReadingXml.cpp
#include "ReadingXml.h"


int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE , LPTSTR cmdLine, int cmdShow){
     ReadingXml app;
     return app.BeginDialog(IDI_READINGXML, hInstance);
}

void ReadingXml::Window_Open(Win::Event& e)
{
     ::CoInitialize(NULL);
     try
     {
          VARIANT_BOOL ok(false);
          _variant_t fileName("people.xml");
          //_____________________________________________________ Load the XML File: people.xml
          IXMLDOMDocumentPtr document;
          HRESULT hr = document.CreateInstance(__uuidof(DOMDocument));
          if (FAILED(hr)) throw _com_error(hr);
          document->load(fileName, &ok);
          //_____________________________________________________ Get the List of Nodes (friend list)
          IXMLDOMNodeListPtr list;
          document->getElementsByTagName(_bstr_t(L"friend"), &list);
          //_____________________________________________________ Get Node Count
          long friendCount = 0;
          list->get_length(&friendCount);
          //_____________________________________________________ Travel node by node (Friend by Friend)
          list->reset();
          IXMLDOMNodePtr node;
          IXMLDOMNodeListPtr children;
          IXMLDOMNodePtr child;
          DOMNodeType nodeType;
          long childrenCount = 0;
          _bstr_t text;
          for(long i = 0; i < friendCount; i++)
          {
               list->get_item(i, &node);
               //____________________________ Get Child Node List
               node->get_childNodes(&children);
               children->get_length(&childrenCount);
               for(long j = 0; j < childrenCount; j ++)
               {
                    children->get_item(j, &child);
                    child->get_nodeType(&nodeType);
                    if (nodeType != NODE_ELEMENT) continue;
                    child->get_text(&text.GetBSTR());
                    this->tbxOutput.Text += text.GetBSTR();
                    this->tbxOutput.Text += L"\r\n";
               }
               this->tbxOutput.Text += L"_______________________\r\n";
          }
     }
     catch(_com_error e)
     {
          this->MessageBox(e.ErrorMessage(), L"Using MS XML", MB_OK | MB_ICONERROR);
     }
     ::CoUninitialize();
}


ReadingXmlRun

Problem 9
Work in groups of four student to discuss:(a) Which is it easier to implement in a program: Save or Load XML.(b) In the variable IXMLDOMDocumentPtr of the previous code, what is the meaning of the letter "I" located at the beginning?(c) In the variable IXMLDOMDocumentPtr of the previous code, what is the meaning of "DOM"?(d) In the variable IXMLDOMDocumentPtr of the previous code, what is the meaning of "Ptr" at the end of the variable?
Trabaje en grupos de cuatro estudiantes para discutir:(a) Cuál es más fácil de implementar en un programa: Guardar o Cargar XML.(b) En la variable IXMLDOMDocumentPtr del código previo, Cuál es el significado de la letra "I" del principio?(c) En la variable IXMLDOMDocumentPtr del código previo, Cuál es el significado de "DOM"?(d) En la variable IXMLDOMDocumentPtr del código previo, Cuál es el significado de la "Ptr" de al final?

Problem 10
Work in groups of four student to design a class to process XML. You must indicate:
  • Public member functions
  • Public member variables
  • Private member functions
  • Private member variables

Trabaje en grupos de cuatro estudiantes para diseñar una clase para procesar XML. Usted debe indicar:
  • Funciones miembro públicas
  • Variables miembro públicas
  • Funciones miembro privadas
  • Variables miembro privadas

Problem 11
Work in groups of four student to explain the Sys::Xml class of any Wintempla project. You must indicate:
  • The method to open an XML file (how it works)
  • The method to save an XML file (how it works)
  • How recursion is implemented (i.e., how children nodes are stored)
  • How attributes are stored
  • How tag names are stored
  • How node values are stored

Trabaje en grupos de cuatro estudiantes para explicar la clase Sys::Xml de cualquier proyecto de Wintempla. Usted debe indicar:
  • El método para abrir un archivo de XML (cómo opera)
  • El método para guardar un archivo de XML (cómo opera)
  • Cómo recursión es almacenada (esto es: cómo los nodos hijos son almacenados)
  • Cómo se almacenan los atributos
  • Cómo se almacenan los nombres de las etiquetas
  • Cómo se almacenan los valores de los nodos

Problem 12
Wintempla provides the Sys::Xml class to create and read XML. Each node has a vector of Sys::Xml to store its children. Create a Wintempla Dialog application called EasyXml. Use Wintempla to insert a textbox called tbxOutput. Set the multiline property of the textbox. Copy the people.xml file to the folder project.
Wintempla proporciona la clase Sys::Xml para crear y leer XML. Cada nodo tiene un vector de Sys::Xml para almacenar sus niños. Cree una aplicación de diálogo de Wintempla llamada EasyXml. Use Wintempla para inserta una caja de texto llamada tbxOutput. Fije la propiedad de multi-línea en la caja de texto. Copie el archivo people.xml en la carpeta del proyecto.

EasyXml.h
#pragma once //______________________________________ EasyXml.h
#include "Resource.h"
class EasyXml: public Win::Dialog
{
public:
     EasyXml()
     {
     }
     ~EasyXml()
     {
     }
     void DisplayNode(Sys::Xml& xmlNode);
     void DisplayNameAndValue(const wstring& name, const wstring& value);
protected:
     ...
};


EasyXml.cpp
...
void EasyXml::Window_Open(Win::Event& e)
{
     Sys::Xml root;
     const wchar_t* error = root.Load(L"people.xml");
     if (error != NULL)
     {
          this->MessageBox(error, L"EasyXml", MB_OK | MB_ICONERROR);
          return;
     }
     DisplayNode(root);
}

void EasyXml::DisplayNode(Sys::Xml& xmlNode)
{
     DisplayNameAndValue(xmlNode.name, xmlNode.value);
     tbxOutput.Text += L"\r\n";
     //____________________________________________ Attributes
     if (xmlNode.attribute.empty() == false)
     {
          tbxOutput.Text += L"*ATTRIBUTES OF ";
          tbxOutput.Text += xmlNode.name;
          tbxOutput.Text += L"\r\n";
          map<wstring, wstring>::iterator attb = xmlNode.attribute.begin();
          const map<wstring, wstring>::iterator aend = xmlNode.attribute.end();
          for( ; attb != aend; attb++)
          {
               DisplayNameAndValue(attb->first, attb->second);
               tbxOutput.Text += L"\r\n";
          }
     }
     //____________________________________________ Children
     if (xmlNode.child.empty() == false)
     {
          tbxOutput.Text += L"*CHILDREN OF ";
          tbxOutput.Text += xmlNode.name;
          tbxOutput.Text += L"\r\n";
          list<Sys::Xml>::iterator child_node;
          const list<Sys::Xml>::iterator last_child = xmlNode.child.end();
          for (child_node = xmlNode.child.begin(); child_node != last_child; child_node++)
          {
               DisplayNode(*child_node);
          }
     }
}

void EasyXml::DisplayNameAndValue(const wstring& name, const wstring& value)
{
     if (name.empty() == true) return;
     tbxOutput.Text += name;
     if (value.empty() == false)
     {
          tbxOutput.Text += L"=";
          tbxOutput.Text += value;
     }
}


EasyXmlRun

Problem 13
javaRepeat the previous problem using Java. In Java, it is possible to parse XML using: the Document Object Model (DOM), or using SAX. In both cases, you need to have installed the Java API for XML (JAXP). In the example below, we will use SAX. To use SAX you need to create a class derived from DefaultHandler that implements functions, in this case we will override: startElement, endElement, and characters.
javaRepita el problema anterior usando Java. En Java, es posible convertir texto a XML usando: El Modelo del Objeto del Documento DOM, o usando SAX. En ambos casos, usted necesita tener instalado la API de Java para XML (JAXP.) En el ejemplo de abajo usaremos SAX. Para usar SAX usted necesita crear una clase derivada de DefaultHandler que implemente algunas funciones, en este caso nosotros sobrecargaremos: startElement, endElement, y characters.

EasyXmlJRun

XmlHandler.java
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class XmlHandler extends org.xml.sax.helpers.DefaultHandler
{
     public String output = null;
     public XmlHandler()
     {
          output = "";
     }

     public void startElement(String namespaceUri, String localName, String qualifiedName, Attributes attributes) throws SAXException
     {
          output += "_______________ Begin of ";
          output += qualifiedName;
          output += "\r\n";
          final int numAttributes = attributes.getLength();
          int i;
          for (i = 0; i < numAttributes; i++)
          {
               output += attributes.getValue(i).toString();
               output += "\r\n";
          }
     }

     public void endElement(String namespaceUri, String localName, String qualifiedName) throws SAXException
     {
          output += "_______________ End of ";
          output += qualifiedName;
          output += "\r\n";
     }

     public void characters(char[] chars, int startIndex, int endIndex) throws SAXException
     {
          String data = new String(chars, startIndex, endIndex);
          output += data;
          output += "\r\n";
     }
}


EasyXmlJ.java
import org.xml.sax.Attributes; //import jdk.internal.org.xml.sax.Attributes;
import org.xml.sax.SAXException; // import jdk.internal.org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;

public class EasyXmlJ extends JFrame
{
     private JTextArea tbxOutput;

     public EasyXmlJ()
     {
          this.setTitle("EasyXmlJ");
          this.setSize(600, 900);
          this.addWindowListener(new ExitListener());                    //_________________________________________________________________________ Create GUI
          Container pane = this.getContentPane();
          pane.setLayout(new FlowLayout());
          tbxOutput = new JTextArea(30, 70);
          pane.add(tbxOutput);
          //_______________________________________________________________________ Parse the file content
          XmlHandler xmlHandler = new XmlHandler();
          SAXParserFactory factory = SAXParserFactory.newInstance();
          try
          {
               File file = new File("C:\\selo\\vs\\CreateHelp\\Help\\02Wintempla\\24XML\\00XML\\EasyXmlJ\\people.xml");
               SAXParser parser = factory.newSAXParser();
               parser.parse(file, xmlHandler);
               tbxOutput.append(xmlHandler.output);
          }
          catch (Exception e)
          {
               tbxOutput.append(e.toString());
               tbxOutput.append("\r\n");
          }

     }

     public static void main(String[] args)
     {
          EasyXmlJ frame = new EasyXmlJ();
          frame.pack();
          frame.setVisible(true);
     }

     public class ExitListener extends WindowAdapter
     {
          public void windowClosing(WindowEvent e)
          {
               System.exit(0);
          }
     }
}


Problem 14
Repeat the previous problem using Android. Edit the activity_main.xml file to have a TextView called tbxOutput. Call your project EasyXmlA.
Repita el problema anterior usando Android. Edite el archivo activity_mail.xml para tener una TextView llamada tbxOutput. Llame a su proyecto EasyXmlA.

EasyXmlARun

ClientXml_activity_main_xml

Step A
Add a new class called XmlHandler as shown. Edit the file as shown (this file is the same as the Java application).
Agregue una clase nueva llamada XmlHandler como se muestra. Edite el archivo como se muestra (este archivo es el mismo que el de la aplicación de Java).

EasyXmlA_XmlHandler

Step B
Edit the MainActivity.java file as shown.
Edite el archivo MainActivity.java como se muestra.

MainActivity.java
package com.selo.easyxmla;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.widget.TextView;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class MainActivity extends Activity
{
     @Override
     protected void onCreate(Bundle savedInstanceState)
     {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          TextView tbxOutput = (TextView)findViewById(R.id.tbxOutput);
          //_______________________________________________________________________ Parse the file content
          XmlHandler xmlHandler = new XmlHandler();
          SAXParserFactory factory = SAXParserFactory.newInstance();
          try
          {
               SAXParser parser = factory.newSAXParser();
               InputStream inputStream = new ByteArrayInputStream(GetXml().getBytes(StandardCharsets.UTF_8));
               parser.parse(inputStream, xmlHandler);
               tbxOutput.append(xmlHandler.output);
          }
          catch (Exception e)
          {
               tbxOutput.append(e.toString());
               tbxOutput.append("\r\n");
          }
     }

     public String GetXml()
     {
          String output = "";
          output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
          output += "<people>\r\n";
          output += "<friend ssn=\"455-45-3434\">\r\n";
          output += "<first_name>Mary</first_name>\r\n";
          output += "<last_name>Smith</last_name>\r\n";
          output += "<age>20</age>\r\n";
          output += "<email>mary@yahoo.com</email>\r\n";
          output += "<!-- This is her home number as she does not have a cell yet -->\r\n";
          output += "<phone>415-456-8945</phone>\r\n";
          output += "<sex>female</sex>\r\n";
          output += "</friend>\r\n";
          output += "<friend ssn=\"556-22-3446\">\r\n";
          output += "<first_name>Peter</first_name>\r\n";
          output += "<last_name>Ferry</last_name>\r\n";
          output += "<age>22</age>\r\n";
          output += "<email>peter@live.com</email>\r\n";
          output += "<phone>212-356-4545</phone>\r\n";
          output += "<sex>male</sex>\r\n";
          output += "</friend>\r\n";
          output += "<friend ssn=\"877-77-3999\">\r\n";
          output += "<first_name>Jim</first_name>\r\n";
          output += "<last_name>Tore</last_name>\r\n";
          output += "<age>17</age>\r\n";
          output += "<email>jimmy@live.com</email>\r\n";
          output += "<phone>210-153-8422</phone>\r\n";
          output += "<sex>male</sex>\r\n";
          output += "</friend>\r\n";
          output += "</people>\r\n";
          return output;
     }
}


Problem 15
Create a Dialog application called ClientXml using Wintempla to create an XML object.
Cree una aplicación de diálogo llamada ClientXml usando Wintempla para crear un objeto de XML.

ClientXmlRun

ClientXml.cpp
...
void ClientXml::Window_Open(Win::Event& e)
{
     Sys::Xml xml;
     xml.name = L"clients";
     //________________________________________ Client 0
     Sys::Xml& client0 = xml.AddChild(L"client");
     client0.AddChild(L"name", L"John Smith");
     client0.AddChild(L"age", L"22");
     //________________________________________ Client 1
     Sys::Xml& client1 = xml.AddChild(L"client");
     client1.AddChild(L"name", L"Mary Miller");
     client1.AddChild(L"age", L"44");
     //
     wstring text;
     xml.GetXmlText(text);
     this->tbxOutput.Text = text;
}


Problem 16
javaRepeat the previous problem using Java. We will create the class called XmlWritter to ease the creation of XML.
javaRepita el problema anterior usando Java. Nosotros crearemos la clase llamada XmlWriter para facilitar la creación de XML.

ClientXmlJRun

XmlWriter.java
public class XmlWriter
{
     private boolean isUtf8 = true;
     public int indentationLevel = 0;
     public String content = "";
     private String rootNodeName = "root";

     public XmlWriter(boolean isUtf8, String rootNodeName)
     {
          this.isUtf8 = isUtf8;
          this.rootNodeName = rootNodeName;
          indentationLevel = 0;
          if (isUtf8 == true)
          {
               content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
          }
          else
          {
               content = "<?xml version=\"1.0\"?>\r\n";
          }
          content += "<";
          content += rootNodeName;
          content += ">\r\n";
          indentationLevel++;
     }

     public String getContent()
     {
          // Use isUtf8 to return the proper content encoding (UTF-8 o UTF-16)
          String output = content;
          output += "</";
          output += rootNodeName;
          output += ">\r\n";
          indentationLevel--;
          return output;
     }

     public void childBegin(String childName)
     {
          indentation();
          content += "<";
          content += childName;
          content += ">\r\n";
          indentationLevel++;
     }

     public void childEnd(String childName)
     {
          indentationLevel--;
          indentation();
          content += "</";
          content += childName;
          content += ">\r\n";
     }

     public void element(String name, String value)
     {
          indentation();
          content += "<";
          content += name;
          content += ">";
          content += ToXml(value);
          content += "</";
          content += name;
          content += ">\n";
     }

     public void indentation()
     {
          int i;
          for(i = 0; i < indentationLevel; i++)
          {
               content += " ";
          }
     }


     public static String ToXml(String input)
     {
          final int len = input.length();
          if (len == 0) return "";
          String output ="";
          int i;
          for(i = 0; i < len; i++)
          {
               switch(input.charAt(i))
               {
                    ...
               }
          }
          return output;
     }
}


XmlWriter_Java

ClientXmlJ.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ClientXmlJ extends JFrame
{
     private JTextArea tbxOutput;

     public ClientXmlJ()
     {
          this.setTitle("ClientXmlJ");
          this.setSize(600, 900);
          this.addWindowListener(new ExitListener());
          //________________________________ Create GUI
          Container pane = this.getContentPane();
          pane.setLayout(new FlowLayout());
          tbxOutput = new JTextArea(30, 70);
          pane.add(tbxOutput);
          //_____________________________________ XML
          XmlWriter xw = new XmlWriter(true, "clients");
          //________________________________________ Client 0
          xw.childBegin("client");
          xw.element("name", "John Smith");
          xw.element("age", "22");
          xw.childEnd("client");
          //________________________________________ Client 1
          xw.childBegin("client");
          xw.element("name", "Mary Miller");
          xw.element("age", "44");
          xw.childEnd("client");
          //
          tbxOutput.setText(xw.getContent());
     }

     public static void main(String[] args)
     {
          ClientXmlJ frame = new ClientXmlJ();
          frame.pack();
          frame.setVisible(true);
     }

     public class ExitListener extends WindowAdapter
     {
          public void windowClosing(WindowEvent e)
          {
               System.exit(0);
          }
     }
}


Problem 17
Repeat the previous problem using Android. Insert a TextView called tbxOutput to display the output of the program. Use the XmlWriter class created in the previous problem. Call your proyect
Repita el problema anterior usando Android. Inserte un TextView llamado tbxOutput para mostrar la salida de su programa. Use la clase XmlWriter creada en el problema previo.

ClientXmlARun

MainActivity.java
package com.selo.clientxmla;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity
{
     @Override
     protected void onCreate(Bundle savedInstanceState)
     {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          TextView tbxOutput = (TextView)findViewById(R.id.tbxOutput);
          //_____________________________________ XML
          XmlWriter xw = new XmlWriter(true, "clients");
          //________________________________________ Client 0
          xw.childBegin("client");
          xw.element("name", "John Smith");
          xw.element("age", "22");
          xw.childEnd("client");
          //________________________________________ Client 1
          xw.childBegin("client");
          xw.element("name", "Mary Miller");
          xw.element("age", "44");
          xw.childEnd("client");
          //
          tbxOutput.setText(xw.getContent());
     }
}



Tip
Wintempla provides the following functions to manipulate XML:
  • Win::ListView::ImportFromXml moves data from a XML object to a list view control
  • Win::ListView::ExportToXml moves data from a list view control to a XML object
  • Sql::SqlConnection::ExecuteSelect moves data from a SQL database to a XML object
  • Sys::Xml::CopyTo moves data from a XML object to a list view control

Wintempla proporciona las siguientes funciones para manipular XML:
  • Win::ListView::ImportFromXml mueve datos desde un objeto de XML a un control de list view
  • Win::ListView::ExportToXml mueve datos desde un control de list view a un objeto de XML
  • Sql::SqlConnection::ExecuteSelect mueve datos desde una base de datos de SQL a un objeto de XML
  • Sys::Xml::CopyTo mueve datos desde un objeto de XML a un control de list view

Problem 18
Create a Dialog application called ClientSql using Wintempla to move data from:
  1. An SQL database to a XML object
  2. A XML object to a list view control
As it is shown in the figure below.

The application displays client information from the database best_buy described in Wintempla > Information System > Sharing .
Cree una aplicación de diálogo llamada ClientSql usando Wintempla para mover datos desde:
  1. Una base de datos de SQL a un objeto de XML
  2. Un objeto de XML a un control de list view
Como se muestra en la figura de abajo.

La aplicación muestra la información de los clientes de la base de datos best_buy descrita en Wintempla > Information System > Sharing.

SQL_XML_ListView

stdafx.h
...
#define CONNECTION_STRING L"DRIVER={SQL Server};server=localhost\\SQLEXPRESS;database=best_buy;Trusted_Connection=yes"


ClientSql.cpp
...
void ClientSql::Window_Open(Win::Event& e)
{
     //______________________________________________________ 1. From SQL to XML
     Sql::SqlConnection conn;
     Sys::Xml xml;
     xml.name = L"client_list"; //root
     Sys::Xml& client = xml.AddChild(L"client");
     client.AddChild(L"client_id");
     client.AddChild(L"last_name");
     client.AddChild(L"first_name");
     client.AddChild(L"city");
     client.AddChild(L"birthdate");
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          conn.ExecuteSelect(L"SELECT client_id, last_name, first_name, city, birthdate FROM client", 100, xml);
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
     }
     wstring text;
     xml.GetXmlText(text);
     this->MessageBox(text, L"ClientSql", MB_OK | MB_ICONINFORMATION);
     //__________________________________________________ 2. From XML to ListView
     lvClient.ImportFromXml(false, xml);
}


ClientSqlTextMsg

ClientSqlRun

Tip
XML can be used to perform transactions among computers running different platforms. DTD files and schemas files are used to check that the information received during a transaction is valid.

Problem 19
Modify the previous problem by adding a button to export to XML the content of the List View control.
Modifique el problema previo agregando un botón para exportar a XML el contenido del control de ListView.

clientXMLfile

ClientSql.cpp
...
bool ClientSql::ExportToXml(Win::ListView& inputListView, const wchar_t* filename)
{
     int i, j;
     //___________________________________________ 1. Get Column Information
     const int colCount = inputListView.GetColumnCount();
     vector<wstring> colName;
     ...
     for (...)
     {
          inputListView.GetColumnText(i, colName[i]);
     }
     //___________________________________________ 2. XML Head
     wstring file_content;
     ...
     //__________________________________________ 3. Render each item
     const int rowCount = inputListView.GetItemCount();
     wstring item_text;
     ...
     for (i = 0; i < rowCount; i++)
     {
          file_content += ...;
          for (j = 0; j < colCount; j++)
          {
               ...
          }
          ...
     }
     ...
     //___________________________________________ 4. Convert to UTF-8
     string utf8_text;
     Sys::Convert::WstringToUTF8(file_content, utf8_text);
     //___________________________________________ Save
     Sys::File file;
     if (file.CreateForWritting(filename) == false) return false;
     return file.WriteText(utf8_text);
}

void ClientSql::btExportToXml_Click(Win::Event& e)
{
     Win::FileDlg dlg;
     dlg.Clear();
     dlg.SetFilter(L"XMLfiles (*.xml)\0*.xml\0\0", 0, L"xml");
     if (dlg.BeginDialog(hWnd, L"Save XML", true) == TRUE)
     {
          if (ExportToXml(lvClient, dlg.GetFileNameFullPath()) == false)
          {
               this->MessageBox(L"Unable to save", L"ClientSql", MB_OK | MB_ICONERROR);
          }
     }
}


Problem 20
Create a program called XmlList with a textbox (multiline and with a vertical scroll bar) and an Open button. When the user clicks the Open button, the user can select an XML file to show the tokens of the file. Create the XmlTokenizer class to promote Object-Oriented Programming. To test your program, use the people.xml file without SSN.
Cree un programa llamado XmlList con una caja de texto (multilínea y con una barra de desplazamiento vertical) y un botón de Abrir. Cuando el usuario hace clic en el botón de abrir, el usuario puede seleccionar un archivo de XML para mostrar los tokens del archivo. Cree la clase XmlTokenizer para promover el uso de la Programación Orientada a Objetos. Para probar su programa, use el archivo people.xml sin el SSN.

XmlListRun1

XmlListRun2

XmlList.h
#pragma once //______________________________________ XmlList.h
#include "Resource.h"
#include "XmlTokenizer.h"
class XmlList: public Win::Dialog
...


XmlList.cpp
...

void XmlList::btOpen_Click(Win::Event& e)
{
     void XmlList::btOpen_Click(Win::Event& e)
{
     Win::FileDlg dlg;
     dlg.SetFilter(L"XML files (*.xml)\0*.xml\0\0", 0, L"xml");
     if (dlg.BeginDialog(hWnd, L"Open XML", false) != TRUE) return;
     XmlTokenizer tokenizer;
     list<wstring> token;
     if (tokenizer.ImportXml(dlg.GetFileNameFullPath(), token) == false)
     {
          this->MessageBox(L"Unable to import", L"XmlViewer", MB_OK | MB_ICONERROR);
     }
     //_______________________________________ Display tokens in textbox
     list<wstring>::iterator p;
     wstring text;
     for (p = token.begin(); p != token.end(); p++)
     {
          text += *p;
          text += L"\r\n";
     }
     tbxOutput.Text = text;
}


XmlTokenizer.h
#pragma once
#pragma once
class XmlTokenizer
{
public:
     XmlTokenizer();
     ~XmlTokenizer();
     bool ImportXml(const wchar_t* filename, list<wstring>& out_token);
private:
     const wchar_t* p;
     void Tag(list<wstring>& out_token);
     bool IsEmpty(const wstring& token);
};


XmlTokenizer.cpp
#include "stdafx.h"
#include "XmlTokenizer.h"

XmlTokenizer::XmlTokenizer()
{
}

XmlTokenizer::~XmlTokenizer()
{
}

bool XmlTokenizer::ImportXml(const wchar_t* filename, list<wstring>& out_token)
{
     //___________________________________________ 1. file > utf8_text
     wstring file_content;
     if (Sys::FileAssistant::TextUtf8Load(filename, file_content) == false) return false;
     //___________________________________________2. Process each tag
     wstring token;
     for (p = file_content.c_str(); *p != L'\0'; p++)
     {
          ...
     }
     return true;
}

void XmlTokenizer::Tag(list<wstring>& out_token)
{
     p++; // move after <
     wstring token;
     for (; p != L'\0'; p++)
     {
          if (*p == '>') //____________________________________ End of tag
          {
               ...
          }
          else if (*p == '/' || *p == '=' || *p == '?') //__________________ Special Characters
          {
               ...
          }
          else if (*p == '\"') //________________________________ "value"
          {
               ...
          }
          else if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') //______________ Spaces, Tabs, Line Breaks or Carriage Returns
          {
               ...
          }
          else
          {
               ...
          }
     }
}

// An empty string has only tabs, spaces, line breaks or carriage returns
bool XmlTokenizer::IsEmpty(const wstring& token)
{
     if (token.empty() == true) return true;
     wstring::const_iterator p;
     for (p = token.begin(); p != token.end(); p++)
     {
          if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') continue;
          return false;
     }
     return true;
}


Problem 21
Create a program called XmlViewer with a ListView control and an Open button. When the user clicks the Open button, the user can select an XML file to show the content of the file in the List View control. Create the XmlReader class to promote Object-Oriented Programming. Use the XmlTokenier class of the previous problem.
Cree un programa llamado XmlViewer con un control de ListView y un botón de Abrir. Cuando el usuario hace clic en el botón de abrir, el usuario puede seleccionar un archivo de XML para mostrar el contenido del archivo en el control de ListView. Cree la clase XmlReader para promover el uso de la Programación Orientada a Objetos. Use la clase XmlTokenizer del problema previo.

XmlViewerRun

XmlViewer.h
#pragma once //______________________________________ XmlViewer.h
#include "Resource.h"
#include "XmlReader.h"
...


XmlViewer.cpp
...
void XmlViewer::Window_Open(Win::Event& e)
{
}

void XmlViewer::btOpen_Click(Win::Event& e)
{
     Win::FileDlg dlg;
     dlg.Clear();
     dlg.SetFilter(L"XML files (*.xml)\0*.xml\0\0", 0, L"xml");
     if (dlg.BeginDialog(hWnd, L"Open XML", false) == TRUE)
     {
          XmlReader reader;
          if (reader.ImportXml(dlg.GetFileNameFullPath(), lvOutput) == false)
          {
               this->MessageBox(L"Unable to import", L"XmlViewer", MB_OK | MB_ICONERROR);
          }
     }
}



XmlReader.h
#pragma once
#include "XmlTokenizer.h"

class XmlReader
{
public:
     XmlReader();
     ~XmlReader();
     bool ImportXml(const wchar_t* filename, Win::ListView& outputListView);
private:
     list<wstring> token;
     list<wstring>::iterator position;

     // <?xml version="1.0" encoding="utf-8"?>
     bool ReadXmlHeader();

     bool ReadChildNode(Win::ListView& outputListView);

     // Read <item> and out_tagname will be "item"
     bool ReadTag(wstring& out_tagname);

     // Read </item> and out_tagname will be "item"
     bool ReadTagEnd(wstring& out_tagname);

     bool ReadElements(const wstring& child_name, Win::ListView& outputListView);
};


XmlReader.cpp
...

bool XmlReader::ImportXml(const wchar_t* filename, Win::ListView& outputListView)
{
     XmlTokenizer xmlTokenizer;
     if (xmlTokenizer.ImportXml(filename, token) == false) return false;
     position = token.begin();
     //___________________________________________ 1. Read XML Header <?xml version="1.0" encoding="utf-8"?>
     if (ReadXmlHeader() == false) return false;
     //___________________________________________ 2. Read Root Node <list>
     wstring root_begin;
     if (ReadTag(root_begin) == false) return false;
     //___________________________________________ 3. Read Child Nodes
     list<wstring>::iterator prev;
     while (position != token.end())
     {
          ReadChildNode(outputListView);
          //___________________________ End of Children?
          prev = position;
          if (*position == L"<")
          {
               position++;
               if (position != token.end())
               {
                    if (*position == L"/")
                    {
                         position = prev; // Move back
                         break;
                    }
               }
          }
          position = prev; // Move back
     }
     //___________________________________________ 4. Read Root Node End
     wstring root_end;
     if (ReadTagEnd(root_end) == false) return false;
     return (root_begin == root_end);
}

bool XmlReader::ReadXmlHeader()
{
     //_____________________________________ <
     if (*position != L"<") return false;
     position++;
     if (position == token.end()) return false;
     ...
     return true;
}


bool XmlReader::ReadTag(wstring& out_tagname)
{
     ...
}

bool XmlReader::ReadTagEnd(wstring& out_tagname)
{
     ...
}

bool XmlReader::ReadChildNode(Win::ListView& outputListView)
{
     //______________________________________________ 1. <item>
     wstring child_name;
     if (ReadTag(child_name) == false) return false;
     //______________________________________________ 2. Read Elements
     ReadElements(child_name, outputListView);
     //______________________________________________ 3. </item>
     wstring child_end_name;
     if (ReadTagEnd(child_end_name) == false) return false;
     return (child_name == child_end_name);
}

bool XmlReader::ReadElements(const wstring& child_name, Win::ListView& outputListView)
{
     wstring element_name;
     wstring element_end_name;
     vector<wstring> column_names;
     vector<wstring> values;
     list<wstring>::iterator prev;
     while (position != token.end())
     {
          //__________________________________________________ End of Child?
          ...
          //_______________________________________________ <last_name>
          if (ReadTag(element_name) == false) return false;
          //_______________________________________________ Smith
          values.push_back(*position);
          position++;
          if (position == token.end()) return false;
          //_______________________________________________ </last_name>
          if (ReadTagEnd(element_end_name) == false) return false;
          if (element_name != element_end_name) return false;
          //
          if (outputListView.GetColumnCount() == 0)
          {
               column_names.push_back(element_name);
          }
     }
     return false;
}

© Copyright 2000-2021 Wintempla selo. All Rights Reserved. Jul 22 2021. Home