Răsfoiți Sursa

Updated text.xml documentation.

Brucey 2 ani în urmă
părinte
comite
835203cf13
1 a modificat fișierele cu 525 adăugiri și 0 ștergeri
  1. 525 0
      xml.mod/doc/intro.bbdoc

+ 525 - 0
xml.mod/doc/intro.bbdoc

@@ -0,0 +1,525 @@
+## What is XML?
+
+XML (eXtensible Markup Language) is a markup language that defines a set of rules for encoding
+documents in a format that is both human-readable and machine-readable. It is designed to store
+and transport data, as well as being a universal standard for data interchange between different
+applications and platforms.
+
+XML files have a hierarchical structure, where data is organized into elements, attributes,
+and text nodes. Elements are the primary building blocks of XML, and they can be nested within each
+other to create a tree-like structure. Attributes provide additional information about elements and
+are defined within the opening tag of an element. Text nodes store the actual content of the elements.
+
+Similar to XML, JSON (JavaScript Object Notation) is another popular format for data interchange,
+which also uses a hierarchical structure to organize data. Both XML and JSON are designed to be
+human-readable and machine-readable, making them well-suited for exchanging data between different
+programming languages and platforms.
+
+However, there are some differences between XML and JSON. While XML relies on tags and attributes to
+define and structure data, JSON uses key-value pairs and objects (denoted by curly braces) or arrays
+(denoted by square brackets) to represent data. In general, JSON is considered to be more compact and less
+verbose than XML, which can result in faster parsing and reduced data size for transmission.
+
+Here's a comparison of XML and JSON representations for the same data:
+
+XML:
+```xml
+<bookstore>
+  <book id="1">
+    <title>Book Title 1</title>
+    <author>Author 1</author>
+    <price>19.99</price>
+  </book>
+  <book id="2">
+    <title>Book Title 2</title>
+    <author>Author 2</author>
+    <price>24.99</price>
+  </book>
+</bookstore>
+```
+
+JSON:
+```json
+{
+  "bookstore": {
+    "book": [
+      {
+        "id": "1",
+        "title": "Book Title 1",
+        "author": "Author 1",
+        "price": 19.99
+      },
+      {
+        "id": "2",
+        "title": "Book Title 2",
+        "author": "Author 2",
+        "price": 24.99
+      }
+    ]
+  }
+}
+```
+
+## XML by Example
+
+We are going to explore the fundamentals of XML by creating an example book store application.
+This application will manage a list of books, including their titles, authors, publication years,
+prices, and other relevant details. Through this example, we will demonstrate how XML is used to
+organize and structure data, making it easier to store, exchange, and process information.
+
+Our example book store will maintain an XML file, books.xml, which contains the following book data:
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<bookstore>
+
+<book category="cooking">
+  <title lang="en">Everyday Italian</title>
+  <author>Giada De Laurentiis</author>
+  <year>2005</year>
+  <price>30.00</price>
+</book>
+
+<book category="children">
+  <title lang="en">Harry Potter</title>
+  <author>J K. Rowling</author>
+  <year>2005</year>
+  <price>29.99</price>
+</book>
+
+<book category="web">
+  <title lang="en">XQuery Kick Start</title>
+  <author>James McGovern</author>
+  <author>Per Bothner</author>
+  <author>Kurt Cagle</author>
+  <author>James Linn</author>
+  <author>Vaidyanathan Nagarajan</author>
+  <year>2003</year>
+  <price>49.99</price>
+</book>
+
+<book category="web" cover="paperback">
+  <title lang="en">Learning XML</title>
+  <author>Erik T. Ray</author>
+  <year>2003</year>
+  <price>39.95</price>
+</book>
+
+</bookstore>
+```
+__Source:__ https://www.w3schools.com/xml/books.xml
+
+In this XML file, each book is represented as a separate element node, with the books nested within
+the parent "bookstore" element. Element nodes can contain attributes, such as "category" or "lang",
+and they can wrap either text or child element nodes.
+
+For instance, the last book in our example has a "category" attribute with the value "web" and a
+"cover" attribute with the value "paperback". This book also has multiple authors, which
+demonstrates that element nodes can contain multiple child nodes of the same type.
+
+#### Nodes
+
+In XML, the DOM (Document Object Model) represents everything within an XML file as a node.
+A node is a fundamental component of an XML document, and there are various types of nodes,
+including element nodes, attribute nodes, and text nodes. Understanding these different node
+types is crucial for effectively working with XML data.
+
+* **Element nodes** : These are the primary building blocks of an XML document, representing
+the XML tags and their content. In our example, `<book>` is an element node. Element nodes can
+be nested within one another, creating a tree-like structure that organizes the data.
+
+* **Attribute nodes** : These nodes provide additional information about an element node and are
+defined within the opening tag of the element. For instance, the category attribute in the `<book>`
+element is an attribute node. Attribute nodes are associated with a specific element and cannot exist
+on their own.
+
+* **Text nodes** : These nodes store the actual content within element nodes. In our example, the
+text "Everyday Italian" within the `<title>` element is a text node.
+
+For simplicity, we will often refer to them as elements, attributes, and text.
+
+#### Analyzing an XML file
+
+Examining an XML file allows us to extract various valuable information, such as:
+
+* **File encoding, XML version, and root node name** : These metadata details are essential for processing
+and interpreting the XML file. In our example, the file encoding is UTF-8, the XML version is 1.0,
+and the root node name is "bookstore."
+
+* **Attributes of nodes** : Attributes provide extra information about elements, such as
+categorization, language, or other properties. In our book store example, the "category" and
+"lang" attributes are used to classify books and specify the language of the titles, respectively.
+
+* **Content of nodes** : The content within nodes can be either text or other nodes, representing
+data or further organization of the XML structure. In our example, the `<book>` element contains
+both text nodes (e.g., the book title) and child element nodes (e.g., the `<author>` element).
+
+* **Number of nodes, attributes in a node, and children of a node** : Counting and understanding the
+relationships between nodes, their attributes, and their children is vital for navigating and manipulating
+XML data effectively. For instance, knowing the number of books in the bookstore or the number of
+authors for a particular book can be useful for various operations and analyses.
+
+### Reading XML Files
+To read data from an existing XML file, you first need to create an #XmlDoc instance and parse
+the `books.xml` file.
+
+```blitzmax
+Local xmlDoc:XmlDoc = new XmlDoc.parseFile("books.xml")
+```
+
+However, we also want to store the book data as objects in BlitzMax,
+so we'll create a custom Type for it first. As you observed in the XML file, the book titles
+can be in different languages, so we need to ensure that we can identify them using the lang
+attribute of the `<title>` element. We can achieve this with a key-value mapping using a #StringMap.
+For authors, since they are not identified by a key, we can use a simple String array to store them.
+
+```blitzmax
+Type TBook
+    Field category:String
+    Field cover:String
+    Field title:StringMap
+    Field authors:String[]
+    Field year:Int
+    Field price:Float
+End Type
+```
+_(Note: Using floating-point numbers for financial values should generally be avoided,
+as it can lead to rounding errors, which is undesirable in financial contexts. For the sake
+of simplicity, we'll use `Float` in this example.)_
+
+Now that we have parsed the XML file and created the `TBook` type to store the information,
+we are ready to read the data from the XML and store it in our custom class.
+
+To extract information from the nodes in the parsed XML file, we can start by retrieving
+the root node using the `getRootElement()` method provided by the XmlDoc instance.
+
+```blitzmax
+Local rootNode:XmlNode = xmlDoc.getRootElement()
+```
+
+#XmlNode objects have various methods for setting and retrieving values. While reading our
+XML file, the following methods might prove useful:
+
+* **Finding elements**: `getAttribute()`, `getAttributeList()`, `hasAttribute()`, `getChildren()`,
+`nextSibling()`, `previousSibling()`, and `findElement()` (if you know what you're looking for).
+* **Retrieving content**: `getContent()`.
+
+Now that we have the root node - which is the `<bookstore>` element - we can access its
+children, which in this case are the `<book>` elements. To iterate over all the books,
+we can use the root node's `getChildren()` method, which returns a #TList. We can then
+iterate over this list using a `For EachIn` loop.
+
+```blitzmax
+For local childNode:XmlNode = EachIn rootNode.getChildren()
+    ' read data of interest from childNode
+Next
+```
+
+Let's take a closer look at a typical book entry in our XML file:
+
+```xml
+<book category="web">
+  <title lang="en">XQuery Kick Start</title>
+  <author>James McGovern</author>
+  <author>Per Bothner</author>
+  <author>Kurt Cagle</author>
+  <author>James Linn</author>
+  <author>Vaidyanathan Nagarajan</author>
+  <year>2003</year>
+  <price>49.99</price>
+</book>
+```
+
+To extract information from this book entry, we'll use the following approaches:
+
+* **Category attribute** : Use `getAttribute()` to retrieve the category value.
+* **Title element and `lang` attribute** : Use `getAttribute()` to obtain the language key of the
+title, and `getContent()` to get the title text.
+* **Author, year, and price elements** : These elements only contain text, so we can use `getContent()`
+to read their values.
+
+For each book, we'll create a new TBook instance and add it to a TList that stores all our books.
+In your own projects, you might want to add conditional checks before adding a book to the list.
+For example, you could skip adding a book if certain required data is missing from the XML file
+(e.g., both "title" and "author" are absent). For the purpose of this example, we'll skip checking
+for duplicates or incomplete entries.
+
+```blitzmax
+Local allBooks:TList = New TList
+For Local childNode:TxmlNode = EachIn rootNode.getChildren()
+    ' create a new book instance
+    Local book:TBook = New TBook
+	
+    book.category = childNode.getAttribute( "category" )
+    ' this stays empty if the attribute is not set 
+    book.cover = childNode.getAttribute( "cover" )
+	
+    ' loop over all child nodes and handle them according to
+    ' their name
+    For Local subNode:TxmlNode = EachIn childNode.getChildren()
+        Select subNode.getName()
+            Case "title"
+                Local key:String = subNode.getAttribute( "lang" ).ToLower()
+                Local value:String = subNode.getContent()
+                book.title.Insert(key, value) 
+            Case "author"
+                ' add the "single entry array" to the authors array
+                book.authors :+ [ subNode.getContent() ]
+            Case "year"
+                ' cast the string content value to Int
+                book.year = Int( subNode.getContent() )
+            Case "price"
+                ' cast the string content value to Float
+                book.price = Float( subNode.getContent() )
+        End Select
+    Next
+	
+    ' add the book to our book storage list
+    allBooks.AddLast( book )
+Next
+
+' close the xmlDoc instance
+xmlDoc.Free()
+```
+
+Now that we have successfully extracted all the book information from the XML file and stored
+it in our application, it's time to take the next step. Let's explore how to save our book data back
+to a new XML file. 
+
+### Saving Changes to XML Files
+
+When working with XML files, it's crucial to save your changes periodically.
+In this section, we'll explore the process of saving objects to XML files, otherwise known as
+"serialization." This involves converting the desired data into text format, making it compatible
+with XML file structures.
+
+In our book example, we only have to handle numbers and text data, which simplifies the serialization process.
+To save our data, we'll need a #TxmlDoc object as the foundation and a root node to add our book nodes.
+
+When creating a new #TxmlDoc, it's a good practice to use the `newDoc()` helper function, which allows you
+to specify the XML version to use. This ensures that your output file is consistent with the original
+`books.xml` file format.
+
+For demonstration purposes, we will also print the content of the document using the #TxmlDoc's `saveFile()`
+method (passing "-" skips saving and redirects content to the output):
+
+```blitzmax
+Local exportXmlDoc:TxmlDoc = TxmlDoc.newDoc("1.0")
+Local exportRootNode:TxmlNode = TxmlNode.newNode("bookstore")
+
+' Set the newly created node as the root for the empty document
+exportXmlDoc.setRootElement(exportRootNode)
+
+' Print the content in a formatted manner
+exportXmlDoc.saveFile("-", True, True)
+```
+
+This code will output the following:
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<bookstore />
+```
+
+As you can see, we've successfully created an empty XML file with the correct root element.
+
+In order to save each book, we need to create a new #TxmlNode for each book, along with additional
+nodes or attributes to represent the properties. The BlitzMax XML module simplifies this process
+by allowing you to pass values directly when creating a new child node using `addChild(name, value)`.
+
+```blitzmax
+' Create and attach a new book node under the root node
+Local bookNode:TxmlNode = exportRootNode.addChild("book")
+
+bookNode.setAttribute("category", book.category)
+
+' Iterate over title keys and store the corresponding values
+' Using method chaining, we can save storing the node first
+For local lang:String = EachIn book.title.Keys()
+    Local title:String = String(book.title.ValueForKey(lang))
+    bookNode.addChild("title", title).addAttribute("lang", lang)
+Next
+
+For local author:String = EachIn book.authors
+    bookNode.addChild("author", author)
+Next
+
+bookNode.addChild("year", book.year)
+
+bookNode.addChild("price", book.price)
+```
+
+Now, we can combine all of the code blocks we've discussed so far to accomplish the following tasks:
+
+1. Load the `books.xml` file.
+2. Save all the books as a new file named `books.new.xml`.
+
+By combining these code blocks, you can create a complete solution to read, manipulate, and save
+XML data using BlitzMax. 
+
+```blitzmax
+SuperStrict
+' xml.mod is not automatically imported like brl.mod and pub.mod, so you need to manually import it
+Import text.xml
+
+Type TBook
+    Field category:String
+    Field cover:String
+    Field title:TStringMap = New TStringMap
+    Field authors:String[]
+    Field year:Int
+    Field price:Float
+End Type
+Local allBooks:TList = New TList
+
+' === LOADING ===
+' Load and parse the books.xml file
+Local xmlDoc:TxmlDoc = New TxmlDoc.parseFile("books.xml")
+' Retrieve the root element (bookstore)
+Local rootNode:TxmlNode = xmlDoc.getRootElement()
+
+' Loop through all child nodes (books)
+For Local childNode:TxmlNode = EachIn rootNode.getChildren()
+    ' Create a new TBook instance
+    Local book:TBook = New TBook
+
+    ' Get the book attributes
+    book.category = childNode.getAttribute("category")
+    book.cover = childNode.getAttribute("cover") ' This remains empty if the attribute is not set
+
+    ' Loop through all child nodes of the current book and handle them according to their name
+    For Local subNode:TxmlNode = EachIn childNode.getChildren()
+        Select subNode.getName()
+            Case "title"
+                ' Store the title in the TStringMap using the language as the key
+                Local key:String = subNode.getAttribute("lang").ToLower()
+                Local value:String = subNode.getContent()
+                book.title.Insert(key, value)
+            Case "author"
+                ' Add the author to the authors array
+                book.authors :+ [subNode.getContent()]
+            Case "year"
+                ' Convert the year from a string to an integer
+                book.year = Int(subNode.getContent())
+            Case "price"
+                ' Convert the price from a string to a float
+                book.price = Float(subNode.getContent())
+        End Select
+    Next
+
+    ' Add the TBook instance to the allBooks list
+    allBooks.AddLast(book)
+Next
+
+' Release resources associated with xmlDoc
+xmlDoc.Free()
+
+' === SAVING ===
+' Create a new TxmlDoc with version 1.0
+Local exportXmlDoc:TxmlDoc = TxmlDoc.newDoc("1.0")
+' Create a new root node (bookstore) for the export document
+Local exportRootNode:TxmlNode = TxmlNode.newNode("bookstore")
+
+' Set the new root node as the document's root element
+exportXmlDoc.setRootElement(exportRootNode)
+
+' Loop through all books in the allBooks list
+For Local book:TBook = EachIn allBooks
+    ' Create a new book node under the root node
+    Local bookNode:TxmlNode = exportRootNode.addChild("book")
+
+    ' Set the book's attributes
+    bookNode.setAttribute("category", book.category)
+    If book.cover
+        bookNode.setAttribute("cover", book.cover)
+    EndIf
+
+    ' Add title nodes with their corresponding language attributes
+    For local lang:String = EachIn book.title.Keys()
+        Local title:String = String(book.title.ValueForKey(lang))
+        bookNode.addChild("title", title).addAttribute("lang", lang)
+    Next
+
+    ' Add author nodes
+    For local author:String = EachIn book.authors
+        bookNode.addChild("author", author)
+    Next
+
+    ' Add year and price nodes
+    bookNode.addChild("year", book.year)
+    bookNode.addChild("price", book.price)
+Next
+
+' Save the XML file as books.new.xml with formatting
+exportXmlDoc.saveFile("books.new.xml", True, True)
+' Release resources associated with exportXmlDoc
+exportXmlDoc.free()
+
+' Now, the new XML file has been created with the processed book data from the original XML file.
+' You can check the output in the "books.new.xml" file.
+```
+
+This is the content of the generated `books.new.xml` file:
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<bookstore>
+  <book category="cooking">
+    <title lang="en">Everyday Italian</title>
+    <author>Giada De Laurentiis</author>
+    <year>2005</year>
+    <price>30.0000000</price>
+  </book>
+  <book category="children">
+    <title lang="en">Harry Potter</title>
+    <author>J K. Rowling</author>
+    <year>2005</year>
+    <price>29.9899998</price>
+  </book>
+  <book category="web">
+    <title lang="en">XQuery Kick Start</title>
+    <author>James McGovern</author>
+    <author>Per Bothner</author>
+    <author>Kurt Cagle</author>
+    <author>James Linn</author>
+    <author>Vaidyanathan Nagarajan</author>
+    <year>2003</year>
+    <price>49.9900017</price>
+  </book>
+  <book category="web" cover="paperback">
+    <title lang="en">Learning XML</title>
+    <author>Erik T. Ray</author>
+    <year>2003</year>
+    <price>39.9500008</price>
+  </book>
+</bookstore>
+```
+
+### Summary
+
+Throughout this short guide, we have demonstrated how to create a bookstore application using XML
+files to store and manipulate book data. Here's a recap of the key steps we covered:
+
+1. **Understanding XML Structure** : We examined the hierarchical structure of XML files, which consists
+of elements, attributes, and text nodes. We also touched upon the similarities between XML and JSON.
+
+2. **Creating a Bookstore Example** : We designed an XML file representing a bookstore that contains
+information about various books, including their categories, titles, authors, publication years, and prices.
+
+3. **XML Nodes** : We explored the concept of nodes in XML and their various types, including element
+nodes, attribute nodes, and text nodes.
+
+4. **Reading XML Files** : We demonstrated how to read an existing XML file using the #TxmlDoc class
+and parse the book data into our custom `TBook` type.
+
+5. **Storing Book Data** : We created a custom TBook type to store book data within our application and
+added the book instances to a #TList.
+
+6. **Accessing XML Elements** : We retrieved specific elements and their attributes from the XML file
+using various #TxmlNode methods.
+
+7. **Saving XML Files** : We discussed how to serialize our `TBook` objects and save them into a new
+XML file, creating new TxmlNodes for each book and setting their attributes and child nodes accordingly.
+
+By following these steps, we successfully built a bookstore application that reads, processes, and saves book
+data using XML files.