[Gambas-user] Edit XML

Caveat Gambas at ...1950...
Mon Nov 22 11:17:09 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

On Mon, 2010-11-22 at 06:48 +0100, Fabien Bodard wrote:
> In fact the problem is simple ... xmldoc is not finalized ... since many year.
> 
> if someone have capabilities and times for it ...
> 
> 2010/11/21 Mauricio Baeza <mauricio at ...2500...>:
> > El sáb, 20-11-2010 a las 13:54 +0100, Caveat escribió:
> >
> >> Hi Mauricio
> >>
> >> Sorry for the late reply, I was doing a lot of thinking. :-)
> >>
> >> Perhaps you might like something along these lines:
> >>
> >> XMLRewriter is a class in a little project I've been working on.  The
> >> idea of XMLRewriter is that it should be capable of parsing any XML
> >> input and applying edits to it to create a new output XML.  The
> >> XMLRewriter class itself does not need to know anything about the XML
> >> it's being fed, as it automagically builds an internal data model of the
> >> provided XML. :-D
> >>
> >> Let me know if you're interested in taking this further, perhaps we can
> >> go off-list to get into the details.
> >>
> >> Regards,
> >> Caveat
> >>
> >> On Mon, 2010-11-15 at 22:58 -0600, Mauricio Baeza wrote:
> >>
> >> > Hi all ...
> >> >
> >> > With the library for XML I can, without problems ...
> >> > 1 .- Create new XML file
> >> > 2 .- Read any XML file
> >> >
> >> > What I can not do is change just one attribute of an element of an
> >> > existing file. Does anyone have a sample?
> >> >
> >> > Greetings
> >> >
> >> >
> >> >
> >>
> >
> >
> >
> > Hello ...
> >
> > Thanks for the reply ...
> >
> > I really just want to know how to edit an attribute of an element.
> > Currently I have solved simply not adding the attribute to first create
> > the XML. Then add it as follows:
> >
> > DIM oDocXMLTmp AS NEW XmlDocument
> > DIM sTmp AS String
> >
> >    oDocXMLTmp.FromString(docXML)
> >    oDocXMLTmp.Root.NewAttribute("sello", Sello)
> >    sTmp = oDocXMLTmp.ToString()
> >
> > But the stamp is the final attribute. To be in the order I want, I need
> > to add it to create the XML and then edit. Which I could not. If only
> > you could help me with this, much will thank you.
> >
> > Best regards
> >
> >
> > --
> > Mauricio Baeza
> >
> > 10 años usando OpenOffice.org, libre, gratuito y seguro
> > _______________________________
> > Todo lo que no es dado es perdido
> > ------------------------------------------------------------------------------
> > Beautiful is writing same markup. Internet Explorer 9 supports
> > standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
> > Spend less time writing and  rewriting code and more time creating great
> > experiences on the web. Be a part of the beta today
> > http://p.sf.net/sfu/msIE9-sfdev2dev
> > _______________________________________________
> > Gambas-user mailing list
> > Gambas-user at lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/gambas-user
> >
> 
> 
> 






More information about the User mailing list