[Gambas-user] Edit XML

Benoît Minisini gambas at ...1...
Mon Nov 22 11:25:42 CET 2010


> Hi Fabien
> 
> The code I have written acts as a kind of generic interface between the
> existing Gambas XMLReader and XMLWriter.  The question is, does this go
> some way to "completing xmldoc"?
> 
> The code consists of:
> XMLParserToModel
> XMLContainer
> XMLRewriter
> 
> The important thing to note here is that my XMLParserToModel should be
> able to read *ANY* XML and create an internal model of it, in a set of
> XMLContainers.  I have tried it with hand-written XML, and with examples
> from t'internet.
> 
> The XMLContainer object I've created is capable of holding a
> hierarchical structure with XMLContainers that themselves hold
> Collections of XMLContainer objects.  Each XMLContainer also holds the
> Node Text (if applicable) and any Attributes for that Node.  When
> created, an XMLContainer knows its parent XMLContainer but as the object
> model is built, the XMLContainers morph into children of their parents.
> 
> The XMLRewriter is really just a demonstration class to show how, using
> the XMLParserToModel to build a model of your XML and the XMLContainer's
> built-in searching to inspect and alter your XML, you can create edits
> which alter specific elements of your original XML.  Any changed XML can
> be seen as a String (use toXMLString on an XMLContainer) or written to a
> new XML file (use writeXML in the XMLRewriter class, which calls out to
> writeSelf on the root XMLContainer).
> 
> Here's a transcript of a session paying with the new objects, I think
> they are quite powerful.  Remember there's NO code in the 3 classes
> described above that knows anything about orders or priorities, or CDs
> or catalogs, or heroes or villains etc.
> 
> *************** Provide some sample XML as a String ***************
> inputString = <?xml version="1.0"
> encoding="ISO-8859-1"?><?xml-stylesheet type = "text/css" href =
> "cd_catalog.css"?><all_orders><order
> priority="rush"><id>20101120123</id><desc>rubber
> duck</desc></order><order priority="normal"><id>20101120123</id><desc>s
> ponge</desc></order></all_orders>
> *************** Now parse the XML *********************************
> parserToModel.parseInputString(inputString)
> *************** Get the model out of the parserToModel object and ask it
> to represent itself as XML ***************
> parserToModel.getModel().toXMLString()
> 
> <all_orders>
> <order priority="rush">
> <id>20101120123</id>
> <desc>rubber duck</desc></order>
> <order priority="normal">
> <id>20101120123</id>
> <desc>sponge</desc></order></all_orders>
> ***************************************************************************
> ****************************************
> 
> *************** Now read sample XML from a file (from
> http://www.w3schools.com/xml/cd_catalog.xml) ***************
> parserToModel.parseInputFile(User.Home &/ "dev" &/ "cd_catalog.xml")
> *************** Pick out the Node(s) containing an ARTIST text entity
> with the text Kim Larsen ***************
> parserToModel.getModel().findSuperNodesByText("Kim Larsen", "ARTIST",
> selectArtists, NULL)
> *************** Ask them to represent themselves as XML strings
> ***************
> FOR EACH selectArtists
>   PRINT selectArtists[selectArtists.Key].toXMLString()
> NEXT
> 
> <CD>
> <TITLE>Midt om natten</TITLE>
> <ARTIST>Kim Larsen</ARTIST>
> <COUNTRY>EU</COUNTRY>
> <COMPANY>Medley</COMPANY>
> <PRICE>7.80</PRICE>
> <YEAR>1983</YEAR></CD>
> ***************************************************************************
> **** *************** Pick out the Node(s) containing a COUNTRY text entity
> with the text EU ***************
> parserToModel.getModel().findSuperNodesByText("EU", "COUNTRY",
> selectArtists, NULL)
> *************** Ask them to represent themselves as XML strings
> ***************
> FOR EACH selectArtists
>   PRINT selectArtists[selectArtists.Key].toXMLString()
> NEXT
> 
> <CD>
> <TITLE>Eros</TITLE>
> <ARTIST>Eros Ramazzotti</ARTIST>
> <COUNTRY>EU</COUNTRY>
> <COMPANY>BMG</COMPANY>
> <PRICE>9.90</PRICE>
> <YEAR>1997</YEAR></CD>
> 
> <CD>
> <TITLE>Romanza</TITLE>
> <ARTIST>Andrea Bocelli</ARTIST>
> <COUNTRY>EU</COUNTRY>
> <COMPANY>Polydor</COMPANY>
> <PRICE>10.80</PRICE>
> <YEAR>1996</YEAR></CD>
> 
> <CD>
> <TITLE>Black angel</TITLE>
> <ARTIST>Savage Rose</ARTIST>
> <COUNTRY>EU</COUNTRY>
> <COMPANY>Mega</COMPANY>
> <PRICE>10.90</PRICE>
> <YEAR>1995</YEAR></CD>
> 
> <CD>
> <TITLE>Midt om natten</TITLE>
> <ARTIST>Kim Larsen</ARTIST>
> <COUNTRY>EU</COUNTRY>
> <COMPANY>Medley</COMPANY>
> <PRICE>7.80</PRICE>
> <YEAR>1983</YEAR></CD>
> 
> <CD>
> <TITLE>Picture book</TITLE>
> <ARTIST>Simply Red</ARTIST>
> <COUNTRY>EU</COUNTRY>
> <COMPANY>Elektra</COMPANY>
> <PRICE>7.20</PRICE>
> <YEAR>1985</YEAR></CD>
> ***************************************************************************
> **** **************************************************************
> *************** Read the original Heroes input XML (See
> http://pastebin.com/aR11N5uc) ***************
> parserToModel.parseInputFile(User.home &/ "Heroes.xml")
> *************** Look at the original XML we have in our internal data
> model ***************
> parserToModel.getModel().toXMLString()
> 
> <all_characters>
> <characters series="Heroes">
> <heroe id="1", name="Claire Bennet">
> <name>Claire Bennet</name>
> <played_by>Hayden Panettiere</played_by>
> <ability>Rapid cellular regeneration</ability></heroe>
> <heroe id="2", name="Hiro Nakamura">
> <name>Hiro Nakamura</name>
> <played_by>Masi Oka</played_by>
> <ability>Space-time manipulation: teleportation & time
> travel</ability></heroe>
> <villain id="1", name=" Gabriel Sylar">
> <name>Gabriel Sylar</name>
> <played_by>Zachary Quinto</played_by>
> <ability>Understand how things work and multiple other abilities
> acquired</ability></villain></characters>
> <characters series="Banana Splits">
> <heroe id="1", name="Graham">
> <name>Graham</name>
> <played_by>Graham Bell</played_by>
> <ability>Being silly</ability></heroe>
> <heroe id="2", name="Bill">
> <name>Bill</name>
> <played_by>Bill Odie</played_by>
> <ability>Being very silly</ability></heroe>
> <heroe id="3", name="Tim">
> <name>Tim</name>
> <played_by>Tim Brook Taylor</played_by>
> <ability>Being very very
> silly</ability></heroe></characters></all_characters>
> ***************************************************************************
> **************** *************** All existing Text Entities
> in /all_characters/characters/heroe/name with current value "Claire
> Bennet" will be updated to "Banana Pudding" ***************
> rewriter.updateTextByPath("/all_characters/characters/heroe/name",
> "Claire Bennet", "Banana Pudding")
> *************** All existing Text Entities
> in /all_characters/characters/villain/played_by will be updated to
> "Someone evil" regardless of the current content
> rewriter.updateTextByPath("/all_characters/characters/villain/played_by",
> NULL, "Someone evil") *************** All Text Entities with the value
> "Being silly" get updated to "Being a complete donut brain"
> rewriter.updateTextByValue("Being silly", "Being a complete donut
> brain")
> *************** Change the value of the attribute named "id" to "h1" on
> all Entities having an Attribute named "name" with a value of "Claire
> Bennet"
> rewriter.changeAttribute("/all_characters/characters/heroe", "name",
> "Claire Bennet", "id", "h1")
> *************** Change the value of the attribute named "id" to "h2" on
> all Entities having an Attribute named "name" with a value of "Hiro
> Nakamura"
> rewriter.changeAttribute("/all_characters/characters/heroe", "name",
> "Hiro Nakamura", "id", "h2")
> *************** First correct a fault in the XML (Attribute called
> "name" has an erroneous space at the front of the value)
> *************** So this will change the value of the Attribute named
> "name" to "Gabriel Sylar" on all Entities having an Attribute named
> "name" with a value of " Gabriel Sylar" (note the leading space)
> rewriter.changeAttribute("/all_characters/characters/villain", "name", "
> Gabriel Sylar", "name", "Gabriel Sylar")
> *************** Now continue updating the ids
> *************** Write out the new XML from the changed internal data
> model (See http://pastebin.com/T0S96xiS)
> rewriter.writeXML(User.home &/ "dev" &/ "NewHeroes.xml", TRUE, "UTF-8")
> *************** Look at the new XML from the changed internal data model
> ***************
> parserToModel.getModel().toXMLString()
> 
> <all_characters>
> <characters series="Heroes">
> <heroe id="h1", name="Claire Bennet">
> <name>Banana Pudding</name>
> <played_by>Hayden Panettiere</played_by>
> <ability>Rapid cellular regeneration</ability></heroe>
> <heroe id="h2", name="Hiro Nakamura">
> <name>Hiro Nakamura</name>
> <played_by>Masi Oka</played_by>
> <ability>Space-time manipulation: teleportation & time
> travel</ability></heroe>
> <villain id="v1", name="Gabriel Sylar">
> <name>Gabriel Sylar</name>
> <played_by>Someone evil</played_by>
> <ability>Understand how things work and multiple other abilities
> acquired</ability></villain></characters>
> <characters series="Banana Splits">
> <heroe id="b1", name="Graham">
> <name>Graham</name>
> <played_by>Graham Bell</played_by>
> <ability>Being a complete donut brain</ability></heroe>
> <heroe id="b2", name="Bill">
> <name>Bill</name>
> <played_by>Bill Odie</played_by>
> <ability>Being very silly</ability></heroe>
> <heroe id="b3", name="Tim">
> <name>Tim</name>
> <played_by>Tim Brook Taylor</played_by>
> <ability>Being very very
> silly</ability></heroe></characters></all_characters>
> ***************************************************************************
> *************
> 
> Let me know whether you think this approach is worth pursuing...
> 
> Regards,
> Caveat
> 

It is sort of a "simple XML interface" ?

-- 
Benoît Minisini




More information about the User mailing list