#135405 - 2005-03-13 02:25 PM
RFC: ReadXmlString/WriteXmlString
|
Shawn
Administrator
Registered: 1999-08-13
Posts: 8611
|
Realized I probably shoudn't hijack Chris's thread ... in regards to XML and as an offshoot to that thread ...
What I was thinking guys, was to create a matched pair of ReadProfileString/WriteProfileString work-alikes for XML files, to "ease" the interface when one just wants to read/write things like settings, here's a quick prototype of a matched set, plus a snippet of code to demonstrate usage.
break on
$filename = "e:\test.xml"
$xml = LoadXml($filename)
$= WriteXmlValue($xml, "korg/shawn/number", 119)
$= WriteXmlValue($xml, "korg/jose/number", 1772)
$= WriteXmlValue($xml, "korg/jooel/number", 2087)
?"Value=" ReadXmlValue($xml, "korg/jose/number")
SaveXml($xml, $filename)
$xml = 0
exit 1
---
[udf]
Code:
function LoadXml($filename)
dim $, $rootNode
$loadXml = CreateObject("Microsoft.XMLDOM");
if not $loadXml
return
endif
$= $loadXml.Load($filename)
endfunction
function WriteXmlValue($xml, $path, $value)
dim $p, $rootNode, $sectionNode, $parentNode, $childNode
$sectionNode = $xml.SelectSingleNode($path);
if not $sectionNode
$parentNode = $xml
for each $node in split($path,"/")
$p = $p + $node
$sectionNode = $xml.SelectSingleNode($p)
if not $sectionNode
$sectionNode = $xml.CreateElement($node)
$parentNode = $parentNode.AppendChild($sectionNode)
else
$parentNode = $sectionNode
endif
$p = $p + "/"
next
endif
if $sectionNode
$sectionNode.Text = $value
endif
endfunction
function SaveXml($xml, $filename)
$SaveXml = $xml.Save($filename);
endfunction
function ReadXmlValue($xml, $key, optional $defaultValue)
dim $sectionNode
$sectionNode = $xml.SelectSingleNode($key);
if not $sectionNode
$ReadXmlValue = $defaultValue;
else
$ReadXmlValue = $sectionNode.FirstChild.Text;
endif
endfunction
Thoughts ?
|
Top
|
|
|
|
#135406 - 2005-03-13 03:53 PM
Re: RFC: ReadXmlString/WriteXmlString
|
Shawn
Administrator
Registered: 1999-08-13
Posts: 8611
|
Ok, here is an even more powerfull pair of UDF's ... it uses the XML path to read and write, much like a registry key path name. If the path one specifies doesn't exist, the UDF builds the path first, than pokes the value. Here's some examples:
$xmlFile = "e:\t.xml"
$= WriteXmlString($xmlFile, "form1/settings/left", 100)
$= WriteXmlString($xmlFile, "form1/settings/top", 200)
?"value=" ReadXmlString($xmlFile, "form1/settings/top")
[udf]
Code:
function WriteXmlString($filename, $path, $value)
dim $xmlDoc, $rootNode, $sectionNode;
$xmlDoc = CreateObject("Microsoft.XMLDOM");
if not $xmlDoc
return
endif
if not $xmlDoc.Load($filename)
$rootNode = $xmlDoc.createElement("configuration");
$= $xmlDoc.AppendChild($rootNode);
endif
$sectionNode = $xmlDoc.SelectSingleNode("/configuration/" + $path);
if not $sectionNode
$sectionNode = $xmlDoc.documentElement
for each $node in split($path,"/")
$childNode = $xmlDoc.CreateElement($node)
$= $sectionNode.AppendChild($childNode)
$sectionNode = $childNode
next
endif
$sectionNode.Text = $value;
$= $xmlDoc.Save($filename);
return
endfunction
function ReadXmlString($filename, $key, optional $defaultValue)
dim $xmlDoc, $sectionNode
$xmlDoc = CreateObject("Microsoft.XMLDOM")
if not $xmlDoc
return
endif
$= $xmlDoc.Load($filename)
$sectionNode = $xmlDoc.SelectSingleNode("/configuration/" + $key);
if not $sectionNode
$ReadXmlString = $defaultValue;
else
$ReadXmlString = $sectionNode.FirstChild.Text;
endif
endfunction
|
Top
|
|
|
|
#135409 - 2005-03-13 04:58 PM
Re: RFC: ReadXmlString/WriteXmlString
|
Shawn
Administrator
Registered: 1999-08-13
Posts: 8611
|
Ok, with apologies to Chris, borrowing his "loadxml" idea, here is a complete set of UDF's for loading/reading/writing/saving from XML files ... looks like this:
break on
$xml = LoadXml("e:\t.xml")
$= WriteXmlString($xml, "shawn/jose", 100) $= WriteXmlString($xml, "shawn/jose/settings/form1/left", 123)
SaveXml($xml, "e:\t.xml")
$xml = 0
exit 1
[udf] Code:
function LoadXml($filename)
dim $, $rootNode
$loadXml = CreateObject("Microsoft.XMLDOM");
if not $loadXml return endif
if not $loadXml.Load($filename)
$rootNode = $loadXml.createElement("root");
if $rootNode
$= $loadXml.AppendChild($rootNode);
endif
endif
endfunction
function SaveXml($xml, $filename)
$SaveXml = $xml.Save($filename);
endfunction
function WriteXmlString($xml, $path, $value)
dim $rootNode, $sectionNode;
$sectionNode = $xml.SelectSingleNode("/root/" + $path);
if not $sectionNode
$sectionNode = $xml.documentElement
for each $node in split($path,"/")
$childNode = $xml.CreateElement($node)
$sectionNode = $sectionNode.AppendChild($childNode)
next
endif
$sectionNode.Text = $value;
return
endfunction
function ReadXmlString($xml, $key, optional $defaultValue)
dim $sectionNode
$sectionNode = $xml.SelectSingleNode("/root/" + $key);
if not $sectionNode $ReadXmlString = $defaultValue; else $ReadXmlString = $sectionNode.FirstChild.Text; endif
endfunction
|
Top
|
|
|
|
#135414 - 2005-03-13 11:33 PM
Re: RFC: ReadXmlString/WriteXmlString
|
Shawn
Administrator
Registered: 1999-08-13
Posts: 8611
|
Im not expecting any structure ... the structure is user-defined, for example this sequence of calls:
$= WriteXmlValue($xml, "korg/shawn/number", 119) $= WriteXmlValue($xml, "korg/shawn/lastname", "tassie")
will generate XML that looks like this:
Code:
<korg> <shawn> <number>119</number> <lastname>tassie</lastname> </shawn> </korg>
-Shawn
|
Top
|
|
|
|
#135415 - 2005-03-15 01:44 AM
Re: RFC: ReadXmlString/WriteXmlString
|
Jose
Seasoned Scripter
Registered: 2001-04-04
Posts: 693
Loc: Buenos Aires - Argentina
|
Since I am working with Open Office and has plenty of config files stored in xml I have found a very used feature wich is the attrib propertie. This propertie holds values within the XML tag.
Wrote two small UDFs for reading adn writting attributes by its path. WriteXMLattrib() and RearXMLattrib() .
Just run this code wich creates the xml file, if exist c:\temp.
Code:
Break on
$filename = "C:Temp\Shawn.xml"
$xml = LoadXml($filename)
$= WriteXmlValue($xml, "korg/shawn/City", "Toronto")
$= WriteXmlValue($xml, "korg/shawn/Country", "Canada")
$= WriteXmlValue($xml, "korg/shawn/Registred", "17/08/1999")
$= WriteXMLattrib($xml, "korg/shawn", "Id", "5200")
$= WriteXMLattrib($xml, "korg/shawn", "Age", "25")
SaveXml($xml, $filename)
$xml = 0
Open the file and take a look at the values Id and Age, they are attributes of Shawn.
Run this script to see those values.
Code:
Break on
$filename = "C:Temp\Shawn.xml"
$xml = LoadXml($filename)
$ShawnCity = ReadXmlValue($xml, "korg/shawn/City")
$ShawnCountry = ReadXmlValue($xml, "korg/shawn/Country")
$ShawnRegistred = ReadXmlValue($xml, "korg/shawn/Registred")
$ShawnId = RearXMLattrib($xml, "korg/shawn", "Id")
$ShawnAge = RearXMLattrib($xml, "korg/shawn", "Age")
? "Shawn Id Attribute= "+$ShawnId
? "Shawn Age Attribute= "+$ShawnAge
? "Shawn City Value= "+$ShawnCity
? "Shawn Country Value= "+$ShawnCountry
? "Shawn Registred Value= "+$ShawnRegistred
$xml = 0
Sleep 5
Functions:
Code:
Function LoadXml($filename)
Dim $, $rootNode
$loadXml = CreateObject("Microsoft.XMLDOM");
If NOT $loadXml
Return
EndIf
$= $loadXml.Load($filename)
EndFunction
Function WriteXmlValue($xml, $path, $value)
Dim $p, $rootNode, $sectionNode, $parentNode, $childNode
$sectionNode = $xml.SelectSingleNode($path);
If NOT $sectionNode
$parentNode = $xml
For Each $node In Split($path,"/")
$p = $p + $node
$sectionNode = $xml.SelectSingleNode($p)
If NOT $sectionNode
$sectionNode = $xml.CreateElement($node)
$parentNode = $parentNode.AppendChild($sectionNode)
Else
$parentNode = $sectionNode
EndIf
$p = $p + "/"
Next
EndIf
If $sectionNode
$sectionNode.Text = $value
EndIf
EndFunction
Function SaveXml($xml, $filename)
$SaveXml = $xml.Save($filename);
EndFunction
Function ReadXmlValue($xml, $key, optional $defaultValue)
Dim $sectionNode
$sectionNode = $xml.SelectSingleNode($key);
If NOT $sectionNode
$ReadXmlValue = $defaultValue;
Else
$ReadXmlValue = $sectionNode.FirstChild.Text;
EndIf
EndFunction
Function WriteXMLattrib($xml, $Path, $Attr, $Value)
$SelectionTag = $xml.getElementsByTagName($Path)
$AttrTag = $SelectionTag.item(0)
$eu = $AttrTag.SetAttribute($Attr,$Value);
EndFunction
Function RearXMLattrib($xml, $Path, $Attr)
$SelectionTag = $xml.getElementsByTagName($Path)
$AttrName = $SelectionTag.item(0)
$RearXMLattrib =$AttrName.getAttribute($Attr)
EndFunction
I think we are getting to an intresting point, this is very fast and looks good to me.
BTW: I cannot paste XML code cause we "Newbyes" dont have ATTRIBUTES !!! for that sort of pleasures.
_________________________
Life is fine.
|
Top
|
|
|
|
Moderator: Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 590 anonymous users online.
|
|
|