XML Class
Posted: 05 Sep 2020, 15:54
Hello,
I am having some problems with the XML Class. When saving the class always appends the tree and I want it to overwrite. Tried to change this line to no avail. It still appends to the end of file leaving the old stuff in start of file.
Are also having some problems with Transform(), and wonder its possible to get it prettier? Its not as pretty as sXML_Pretty() produces just yet.
This is the output:
and this is what im looking for:
I also tried to circumvent the alfanumerical sorting of the attributes, but that is not possible. Using these lines:
Last question. How do I declare Encoding type in the prolog section when saving file?
XML Class with sample code:
I am having some problems with the XML Class. When saving the class always appends the tree and I want it to overwrite. Tried to change this line to no avail. It still appends to the end of file leaving the old stuff in start of file.
Code: Select all
if(text!=this[])
file:=FileOpen(filename,"w"),file.Write(this[])
;file:=FileOpen(filename,"rw"),file.Seek(0),file.Write(this[]),file.Length(file.Position)
This is the output:
Code: Select all
<?xml version="1.0"?>
<tv>
<programme channel="MTV" start="20200905082500 +0200" stop="20200905092500 +0200">
<title lang="en">Ghosted: Love gone missing</title>
<sub-title lang="en">Mutiny on the Bounty</sub-title>
<desc lang="en">Blablabla</desc>
<date>2020</date>
<episode-num system="onscreen">S21E1</episode-num>
<category lang="en">series</category>
<star-rating system="imdb"><value>6.2/10</value></star-rating>
<review type="url">http://www.imdb.com/title/tt2272918</review></programme>
</tv>
Code: Select all
<?xml version="1.0"?>
<tv>
<programme channel="MTV" start="20200905082500 +0200" stop="20200905092500 +0200">
<title lang="en">Ghosted: Love gone missing</title>
<sub-title lang="en">Mutiny on the Bounty</sub-title>
<desc lang="en">Blablabla</desc>
<date>2020</date>
<episode-num system="onscreen">S21E1</episode-num>
<category lang="en">series</category>
<star-rating system="imdb">
<value>6.2/10</value>
</star-rating>
<review type="url">http://www.imdb.com/title/tt2272918</review>
</programme>
</tv>
Code: Select all
Top := XMLDoc.Add("programme",@XmlType (propOrder={start:"20200905082500 +0200",stop:"20200905092500 +0200",channel:"MTV"}),,0)
;Top := XMLDoc.Add("programme",propOrder={start:"20200905082500 +0200",stop:"20200905092500 +0200",channel:"MTV"},,0)
;Top := XMLDoc.Add("programme",{start:"20200905082500 +0200",stop:"20200905092500 +0200",channel:"MTV"},,0) ;works but attributes are sorted alfanumerical
XML Class with sample code:
Code: Select all
XMLDoc:=new XML("tv", "guide.xml")
Top := XMLDoc.Add("programme",{start:"20200905082500 +0200",stop:"20200905092500 +0200",channel:"MTV"},,0)
XMLDoc.Under(Top,"title",{lang:"en"},"Ghosted: Love gone missing")
XMLDoc.Under(Top,"sub-title",{lang:"en"},"Mutiny on the Bounty")
XMLDoc.Under(Top,"desc",{lang:"en"},"Blablabla")
XMLDoc.Under(Top,"date",,"2020")
XMLDoc.Under(Top,"episode-num",{system:"onscreen"},"S21E1")
XMLDoc.Under(Top,"category",{lang:"en"},"series")
Rating := XMLDoc.Under(Top,"star-rating",{system:"imdb"})
XMLDoc.Under(Rating,"value",,"6.2/10")
XMLDoc.Under(Top,"review",{type:"url"},"http://www.imdb.com/title/tt2272918")
XMLDoc.Transform(2)
XMLDoc.Save()
Class XML{
keep:=[]
__Get(x=""){
return this.XML.xml
}__New(param*){
;temp.preserveWhiteSpace:=1
root:=param.1,file:=param.2,file:=file?file:root ".xml",temp:=ComObjCreate("MSXML2.DOMDocument"),temp.SetProperty("SelectionLanguage","XPath"),this.xml:=temp,this.file:=file,XML.keep[root]:=this
if(FileExist(file)){
FileRead,info,%file%
if(info=""){
this.xml:=this.CreateElement(temp,root)
FileDelete,%file%
}else
temp.LoadXML(info),this.xml:=temp
}else
this.xml:=this.CreateElement(temp,root)
}Add(XPath,att:="",text:="",dup:=0){
p:="/",add:=(next:=this.SSN("//" XPath))?1:0,last:=SubStr(XPath,InStr(XPath,"/",0,0)+1)
if(!next.xml){
next:=this.SSN("//*")
for a,b in StrSplit(XPath,"/")
p.="/" b,next:=(x:=this.SSN(p))?x:next.AppendChild(this.XML.CreateElement(b))
}if(dup&&add)
next:=next.ParentNode.AppendChild(this.XML.CreateElement(last))
for a,b in att
next.SetAttribute(a,b)
if(text!="")
next.text:=text
return next
}CreateElement(doc,root){
return doc.AppendChild(this.XML.CreateElement(root)).ParentNode
}EA(XPath,att:=""){
list:=[]
if(att)
return XPath.NodeName?SSN(XPath,"@" att).text:this.SSN(XPath "/@" att).text
nodes:=XPath.NodeName?XPath.SelectNodes("@*"):nodes:=this.SN(XPath "/@*")
while(nn:=nodes.item[A_Index-1])
list[nn.NodeName]:=nn.text
return list
}Find(info*){
static last:=[]
doc:=info.1.NodeName?info.1:this.xml
if(info.1.NodeName)
node:=info.2,find:=info.3,return:=info.4!=""?"SelectNodes":"SelectSingleNode",search:=info.4
else
node:=info.1,find:=info.2,return:=info.3!=""?"SelectNodes":"SelectSingleNode",search:=info.3
if(InStr(info.2,"descendant"))
last.1:=info.1,last.2:=info.2,last.3:=info.3,last.4:=info.4
if(InStr(find,"'"))
return doc[return](node "[.=concat('" RegExReplace(find,"'","'," Chr(34) "'" Chr(34) ",'") "')]/.." (search?"/" search:""))
else
return doc[return](node "[.='" find "']/.." (search?"/" search:""))
}Get(XPath,Default){
text:=this.SSN(XPath).text
return text?text:Default
}Language(Language:="XSLPattern"){
this.XML.SetProperty("SelectionLanguage",Language)
}ReCreate(XPath,new){
rem:=this.SSN(XPath),rem.ParentNode.RemoveChild(rem),new:=this.Add(new)
return new
}Save(x*){
if(x.1=1)
this.Transform()
if(this.XML.SelectSingleNode("*").xml="")
return m("Errors happened while trying to save " this.file ". Reverting to old version of the XML")
filename:=this.file?this.file:x.1.1,ff:=FileOpen(filename,0),text:=ff.Read(ff.length),ff.Close()
if(!this[])
return m("Error saving the " this.file " XML. Please get in touch with maestrith if this happens often")
if(text!=this[])
file:=FileOpen(filename,"w"),file.Write(this[])
;file:=FileOpen(filename,"rw"),file.Seek(0),file.Write(this[]),file.Length(file.Position)
}SSN(XPath){
return this.XML.SelectSingleNode(XPath)
}SN(XPath){
return this.XML.SelectNodes(XPath)
}Transform(){
static
if(!IsObject(xsl))
xsl:=ComObjCreate("MSXML2.DOMDocument"),xsl.loadXML("<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""><xsl:output method=""xml"" indent=""yes"" encoding=""UTF-8""/><xsl:template match=""@*|node()""><xsl:copy>`n<xsl:apply-templates select=""@*|node()""/><xsl:for-each select=""@*""><xsl:text></xsl:text></xsl:for-each></xsl:copy>`n</xsl:template>`n</xsl:stylesheet>"),style:=null
this.XML.TransformNodeToObject(xsl,this.xml)
}Under(under,node,att:="",text:="",list:=""){
new:=under.AppendChild(this.XML.CreateElement(node)),new.text:=text
for a,b in att
new.SetAttribute(a,b)
for a,b in StrSplit(list,",")
new.SetAttribute(b,att[b])
return new
}
}SSN(node,XPath){
return node.SelectSingleNode(XPath)
}SN(node,XPath){
return node.SelectNodes(XPath)
}m(x*){
active:=WinActive("A")
ControlGetFocus,Focus,A
ControlGet,hwnd,hwnd,,%Focus%,ahk_id%active%
static list:={btn:{oc:1,ari:2,ync:3,yn:4,rc:5,ctc:6},ico:{"x":16,"?":32,"!":48,"i":64}},msg:=[],msgbox
list.title:="XML Class",list.def:=0,list.time:=0,value:=0,msgbox:=1,txt:=""
for a,b in x
obj:=StrSplit(b,":"),(vv:=List[obj.1,obj.2])?(value+=vv):(list[obj.1]!="")?(List[obj.1]:=obj.2):txt.=b "`n"
msg:={option:value+262144+(list.def?(list.def-1)*256:0),title:list.title,time:list.time,txt:txt}
Sleep,120
MsgBox,% msg.option,% msg.title,% msg.txt,% msg.time
msgbox:=0
for a,b in {OK:value?"OK":"",Yes:"YES",No:"NO",Cancel:"CANCEL",Retry:"RETRY"}
IfMsgBox,%a%
{
WinActivate,ahk_id%active%
ControlFocus,%Focus%,ahk_id%active%
return b
}
}