Skip to content

Exploring_XML

hhzl edited this page May 19, 2025 · 34 revisions

XML = Extensible Markup Language

The main purpose of XML is serialization, i.e. storing, transmitting, and reconstructing arbitrary data.

Gathering of existing material ...

Origin of the YAXO parser used in Cuis

YAXO was first introduced in Squeak 3.3.

https://wiki.squeak.org/squeak/2256

4744YAXO – Duane Maxwell, Andres Valloud, Michael Rueger – 25 January 2002 YAX is yet another XML parser. This version is an effort to further integrate the original yax version with the Exobox implementation. The original yax version already was based on some ideas in the Comanche tokenizer and the Exobox parser. The YAX homepage is at http://www.squeaklet.com/Yax/index.html. This change set includes a XMLParser with SAX and DOM support and a XMLWriter.

Introduction https://wiki.squeak.org/squeak/1407

What is XML?

https://www.w3schools.com/xml/xml_whatis.asp

<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

The XML above is quite self-descriptive:

  • It has sender information
  • It has receiver information
  • It has a heading
  • It has a message body

But still, the XML above does not DO anything. XML is just information wrapped in tags.

Installation

Feature require: 'YAXO'

example

XMLDOMParser addressBookXMLWithDTD
XMLDOMParser  parseDocumentFrom: XMLTokenizer addressBookXMLWithDTD readStream

Writing a XML file

https://wiki.squeak.org/squeak/6338

Reading a XML file

https://wiki.squeak.org/squeak/6342

Squeak tutorial

Squeak has an XML tutorial which explains how to access information in a rss page.

doc := HTTPClient httpGetDocument: 'http://source.squeak.org/trunk/feed.rss'.
	XMLDOMParser parseDocumentFrom: (ReadStream on: (doc content)).

for more see Squeak 6.0. adapt it for Cuis; probably not much.

Erudite

Lift out examples from Erudite https://github.com/Cuis-Smalltalk/Erudite

https://raw.githubusercontent.com/Cuis-Smalltalk/Erudite/refs/heads/master/Examples/xmlbook3.xml Add the statement which reads this here

FAO country names example

https://wiki.squeak.org/squeak/6342

(XMLDOMParser parseFileNamed: 'fao_country_names.xml')
  firstNode
  allElementsSelect: [ : each |
    each localName = 'geographical_region' ].

The file fao_country_names.xml seems to be no longer available in XML, see https://data.apps.fao.org/catalog/dataset/country-names

Find another candidate.

Pharo

From Pharo examples https://github.com/pharo-contributions/XML-XMLParser

|xmlString|
xmlString := '<?xml version="1.0" encoding="UTF-8"?>
<countries>
  <country code="af" handle="afghanistan" continent="asia" iso="4">Afghanistan</country>
  <country code="al" handle="albania" continent="europe" iso="8">Albania</country>
  <country code="dz" handle="algeria" continent="africa" iso="12">Algeria</country>
</countries>'.

"adapted for Cuis"

XMLDOMParser  parseDocumentFrom: xmlString readStream

13 year old Pharo video https://www.youtube.com/watch?v=6q78hzawfGU

An example of a XML file standard: MusicXML

https://www.w3.org/2021/06/musicxml40/tutorial/hello-world/

"Hello World" program in MusicXML

xmlString := 
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE score-partwise PUBLIC
    "-//Recordare//DTD MusicXML 4.0 Partwise//EN"
    "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="4.0">
  <part-list>
    <score-part id="P1">
      <part-name>Music</part-name>
    </score-part>
  </part-list>
  <part id="P1">
    <measure number="1">
      <attributes>
        <divisions>1</divisions>
        <key>
          <fifths>0</fifths>
        </key>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
        </time>
        <clef>
          <sign>G</sign>
          <line>2</line>
        </clef>
      </attributes>
      <note>
        <pitch>
          <step>C</step>
          <octave>4</octave>
        </pitch>
        <duration>4</duration>
        <type>whole</type>
      </note>
    </measure>
  </part>
</score-partwise>'.

XMLDOMParser  parseDocumentFrom: xmlString readStream

Exploring MusicXML

Tune: Mary had a little lamb

ABC notation https://abcnotation.com/tunePage?a=trillian.mit.edu/~jc/music/abc/mirror/musicaviva.com/england/mary-had-a-little-lamb-f/0000

MusicXML notation

https://abcnotation.com/getResource/downloads/code_/mary-had-a-little-lamb.xml?a=trillian.mit.edu/~jc/music/abc/mirror/musicaviva.com/england/mary-had-a-little-lamb-f/0000

https://musescore.com/user/34504790/scores/6127202 Clicking the download button offers to download it in MusicXML.

https://abcnotation.com/tunePage?a=trillian.mit.edu/~jc/music/abc/mirror/back.numachi.com/Frere_Jacques/0000 MusicXML https://abcnotation.com/getResource/downloads/code_/frere-jacques.xml?a=back.numachi.com:8000/dtrad/abc_dtrad.tar.gz/abc_dtrad/FRERJACQ/0000

Exercise: expore DrGeo XML reading and writing code

Download current DrGeo Desktop menu -> Tools -> SystemBrowser

Creation of an XMLElement (taken from class side)

XMLNodeWithElements subclass: #XMLElement
	instanceVariableNames: 'name contents attributes'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'YAXO'

Go to XMLElement in the class Browser, class side

Click on method named: aString attributes: attributeList Go for senders of it.

You will find for example how an XMLElement is constructed to write out a rectangle as SVG

DrGSvgCanvas
rectangle: rect
	| rectNode |
	rectNode := XMLElement 
		named: #rect 
		attributes: {
			#x -> rect topLeft x asString . #y -> rect topLeft y asString .
			#width -> rect width asString . #height -> rect height asString } asDictionary.
	^ rectNode

And then this #rectangle: method is called by DrGSvgCanvas #fillRectangle:color:

fillRectangle: rect color: fillColor
	| rectNode |
	rectNode := self rectangle: rect.
	self styleOf: rectNode StrokeWidth: nil color: nil fillColor: fillColor.
	svgTree addElement: rectNode

More attributes are filled in for example

DrSvgCanvas

styleOf: element StrokeWidth: strokeWidth color: strokeColor strokeDashArray: sda strokeDashArrayOffset: sdao fillColor: fillColor
"
	Apply style to a given element (node) 
"
	strokeWidth ifNotNil: [element attributeAt: #'stroke-width' put: strokeWidth asString].
	strokeColor ifNotNil: [		element attributeAt: #stroke put: 
		(strokeColor isTransparent ifTrue: ['transparent'] ifFalse:		strokeColor hexHtml)].
	sda ifNotNil: [
		element 
			attributeAt: #'stroke-dasharray' 
			put: (String streamContents: [:s | sda do: [:e | s store: e] separatedBy: [ s space]])].
	sdao ifNotNil: [element attributeAt: #'stroke-dashoffset' put: sdao asString].
	fillColor 
		ifNotNil: [
			element attributeAt: #fill put: fillColor hexHtml.
			fillColor isOpaque ifFalse: [element attributeAt: #'fill-opacity' put: fillColor alpha asString] ]
		ifNil: [element attributeAt: #fill put: 'none']

pathNode := XMLElement named: #path.

Explore classes:

DrGeoXML DrGSvgCanvas

Next

Next thing to do: Read the MusicXML file, access the tune and play it.

Clone this wiki locally