数组转xml并读取

简单数组例子

Array := [1,2,3]
XA_Save("Array", Path) ;put variable name in quotes

XA_Load(Path) ;the name of the variable containing the array is returned

MsgBox,% Array[3]

生成的xml

<?xml version="1.0" encoding="UTF-8"?>
<Array>
	<Invalid_Name id="1" ahk="True">1</Invalid_Name>
	<Invalid_Name id="2" ahk="True">2</Invalid_Name>
	<Invalid_Name id="3" ahk="True">3</Invalid_Name>
</Array>

关联数组例子

Array := {"中国":{"台湾":"宝岛"},"日本":"岛国"}
XA_Save("Array", Path) ;put variable name in quotes

XA_Load(Path) ;the name of the variable containing the array is returned

MsgBox,% Array["中国"]["台湾"]

生成的xml

<?xml version="1.0" encoding="UTF-8"?>
<Array>
	<中国>
		<台湾>宝岛</台湾>
	</中国>
	<日本>岛国</日本>
</Array>

用到的函数

Path:=A_ScriptDir . "/xmlsave.xml"

Array := [1,2,3]
XA_Save("Array", Path) ;put variable name in quotes

XA_Load(Path) ;the name of the variable containing the array is returned

MsgBox,% Array[3]

Array := {"中国":{"台湾":"宝岛"},"日本":"岛国"}
XA_Save("Array", Path) ;put variable name in quotes

XA_Load(Path) ;the name of the variable containing the array is returned

MsgBox,% Array["中国"]["台湾"]





XA_Save(Array, Path) {
FileDelete, % Path
FileAppend, % "<?xml version=""1.0"" encoding=""UTF-8""?>`n<" . Array . ">`n" . XA_ArrayToXML(Array) . "`n</" . Array . ">", % Path, UTF-8
If (ErrorLevel)
	Return 1
Return 0
}
XA_Load(Path) {
  Local XMLText, XMLObj, XMLRoot, Root1, Root2
  
  If (!FileExist(Path))
	Return 1
	
  FileRead, XMLText, % Path
  
  XMLObj    := XA_LoadXML(XMLText)
  XMLObj    := XMLObj.selectSingleNode("/*")
  XMLRoot   := XMLObj.nodeName
  %XMLRoot% := XA_XMLToArray(XMLObj.childNodes)
  
  Return XMLRoot
}
XA_XMLToArray(nodes, NodeName="") {
   Obj := Object()
	
   for node in nodes
   {
      if (node.nodeName != "#text")  ;NAME
	  {
		If (node.nodeName == "Invalid_Name" && node.getAttribute("ahk") == "True")
		  NodeName := node.getAttribute("id")
		Else
		  NodeName := node.nodeName
	  }
        
      else ;VALUE
		  Obj := node.nodeValue
         
      if node.hasChildNodes
	  {
		;Same node name was used for multiple nodes
		If ((node.nextSibling.nodeName = node.nodeName || node.nodeName = node.previousSibling.nodeName) && node.nodeName != "Invalid_Name" && node.getAttribute("ahk") != "True")
		{
		  ;Create object
		  If (!node.previousSibling.nodeName)
		  {
			Obj[NodeName] := Object()
			ItemCount := 0
		  }
		  
		  ItemCount++
		  
		  ;Use the supplied ID if available
		  If (node.getAttribute("id") != "")
		    Obj[NodeName][node.getAttribute("id")] := XA_XMLToArray(node.childNodes, node.getAttribute("id"))
		
		  ;Use ItemCount if no ID was provided
		  Else
			Obj[NodeName][ItemCount] := XA_XMLToArray(node.childNodes, ItemCount)
	    }
		
		Else
		  Obj.Insert(NodeName, XA_XMLToArray(node.childNodes, NodeName))
	  }
   }
   
   return Obj
}
XA_LoadXML(ByRef data){
   o := ComObjCreate("MSXML2.DOMDocument.6.0")
   o.async := false
   o.LoadXML(data)
   return o
}
XA_ArrayToXML(theArray, tabCount=1, NodeName="") {     
    Local tabSpace, extraTabSpace, tag, val, theXML, root
	tabCount++
    tabSpace := "" 
    extraTabSpace := "" 
	
	if (!IsObject(theArray)) {
	  root := theArray
	  theArray := %theArray%
    }
	
	While (A_Index < tabCount) {
        tabSpace .= "`t" 
		extraTabSpace := tabSpace . "`t"
    } 
     
	for tag, val in theArray {
        If (!IsObject(val))
		{
		  If (XA_InvalidTag(tag))
		    theXML .= "`n" . tabSpace . "<Invalid_Name id=""" . XA_XMLEncode(tag) . """ ahk=""True"">" . XA_XMLEncode(val) . "</Invalid_Name>"
		  Else
			theXML .= "`n" . tabSpace . "<" . tag . ">" . XA_XMLEncode(val) . "</" . tag . ">"
	    }
		
		Else
		{
		  If (XA_InvalidTag(tag))
		    theXML .= "`n" . tabSpace . "<Invalid_Name id=""" . XA_XMLEncode(tag) . """ ahk=""True"">" . "`n" . XA_ArrayToXML(val, tabCount, "") . "`n" . tabSpace . "</Invalid_Name>"
		  Else
		    theXML .= "`n" . tabSpace . "<" . tag . ">" . "`n" . XA_ArrayToXML(val, tabCount, "") . "`n" . tabSpace . "</" . tag . ">"
	    }
    } 
	
	theXML := SubStr(theXML, 2)
	Return theXML
} 
XA_InvalidTag(Tag) {
	Char1      := SubStr(Tag, 1, 1) 
	Chars3     := SubStr(Tag, 1, 3)
	StartChars := "~``!@#$%^&*()_-+={[}]|\:;""'<,>.?/1234567890 	`n`r"
	Chars := """'<>=/ 	`n`r"
	
	Loop, Parse, StartChars
	{
		If (Char1 = A_LoopField)
		  Return 1
	}
	
	Loop, Parse, Chars
	{
		If (InStr(Tag, A_LoopField))
		  Return 1
	}
	
	If (Chars3 = "xml")
	  Return 1
	  
	Return 0
}
XA_XMLEncode(Text) {
StringReplace, Text, Text, &, &, All
StringReplace, Text, Text, <, <, All
StringReplace, Text, Text, >, >, All
StringReplace, Text, Text, ", ", All
StringReplace, Text, Text, ', ', All
Return Text
}

 

 

人已赞赏
3 条回复 A文章作者 M管理员
  1. 这个用法是很棒的,不错,我在一些大应用中见都是用xml,有什么优势?

    • 首先这个例子可以先写定义一个ahk结构化的数据结构,然后生成xml,作为机器常数
      后续通过xml修改读取配置参数。类似于c语言的机构体嵌套定义。
      xml的好处是可以存储树型数据机构,刚研究

    • 嗯嗯

      确实不错!有空尝试一下!

个人中心
购物车
优惠劵
今日签到
搜索