You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.7 KiB

  1. local base = _G
  2. local xml = xml
  3. module("xml")
  4. -- symbolic name for tag index, this allows accessing the tag by var[xml.TAG]
  5. TAG = 0
  6. -- sets or returns tag of a LuaXML object
  7. function tag(var,tag)
  8. if base.type(var)~="table" then return end
  9. if base.type(tag)=="nil" then
  10. return var[TAG]
  11. end
  12. var[TAG] = tag
  13. end
  14. -- creates a new LuaXML object either by setting the metatable of an existing Lua table or by setting its tag
  15. function new(arg)
  16. if base.type(arg)=="table" then
  17. base.setmetatable(arg,{__index=xml, __tostring=xml.str})
  18. return arg
  19. end
  20. local var={}
  21. base.setmetatable(var,{__index=xml, __tostring=xml.str})
  22. if base.type(arg)=="string" then var[TAG]=arg end
  23. return var
  24. end
  25. -- appends a new subordinate LuaXML object to an existing one, optionally sets tag
  26. function append(var,tag)
  27. if base.type(var)~="table" then return end
  28. local newVar = new(tag)
  29. var[#var+1] = newVar
  30. return newVar
  31. end
  32. -- converts any Lua var into an XML string
  33. function str(var,indent,tagValue)
  34. if base.type(var)=="nil" then return end
  35. local indent = indent or 0
  36. local indentStr=""
  37. for i = 1,indent do indentStr=indentStr.." " end
  38. local tableStr=""
  39. if base.type(var)=="table" then
  40. local tag = var[0] or tagValue or base.type(var)
  41. local s = indentStr.."<"..tag
  42. for k,v in base.pairs(var) do -- attributes
  43. if base.type(k)=="string" then
  44. if base.type(v)=="table" and k~="_M" then -- otherwise recursiveness imminent
  45. tableStr = tableStr..str(v,indent+1,k)
  46. else
  47. s = s.." "..k.."=\""..encode(base.tostring(v)).."\""
  48. end
  49. end
  50. end
  51. if #var==0 and #tableStr==0 then
  52. s = s.." />\n"
  53. elseif #var==1 and base.type(var[1])~="table" and #tableStr==0 then -- single element
  54. s = s..">"..encode(base.tostring(var[1])).."</"..tag..">\n"
  55. else
  56. s = s..">\n"
  57. for k,v in base.ipairs(var) do -- elements
  58. if base.type(v)=="string" then
  59. s = s..indentStr.." "..encode(v).." \n"
  60. else
  61. s = s..str(v,indent+1)
  62. end
  63. end
  64. s=s..tableStr..indentStr.."</"..tag..">\n"
  65. end
  66. return s
  67. else
  68. local tag = base.type(var)
  69. return indentStr.."<"..tag.."> "..encode(base.tostring(var)).." </"..tag..">\n"
  70. end
  71. end
  72. -- saves a Lua var as xml file
  73. function save(var,filename)
  74. if not var then return end
  75. if not filename or #filename==0 then return end
  76. local file = base.io.open(filename,"w")
  77. file:write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
  78. file:write(str(var))
  79. base.io.close(file)
  80. end
  81. -- 转换成xml字符串
  82. function toString(var)
  83. if not var then return end
  84. return "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" .. str(var)
  85. end
  86. -- recursively parses a Lua table for a substatement fitting to the provided tag and attribute
  87. function find(var, tag, attributeKey,attributeValue)
  88. -- check input:
  89. if base.type(var)~="table" then return end
  90. if base.type(tag)=="string" and #tag==0 then tag=nil end
  91. if base.type(attributeKey)~="string" or #attributeKey==0 then attributeKey=nil end
  92. if base.type(attributeValue)=="string" and #attributeValue==0 then attributeValue=nil end
  93. -- compare this table:
  94. if tag~=nil then
  95. if var[0]==tag and ( attributeValue == nil or var[attributeKey]==attributeValue ) then
  96. base.setmetatable(var,{__index=xml, __tostring=xml.str})
  97. return var
  98. end
  99. else
  100. if attributeValue == nil or var[attributeKey]==attributeValue then
  101. base.setmetatable(var,{__index=xml, __tostring=xml.str})
  102. return var
  103. end
  104. end
  105. -- recursively parse subtags:
  106. for k,v in base.ipairs(var) do
  107. if base.type(v)=="table" then
  108. local ret = find(v, tag, attributeKey,attributeValue)
  109. if ret ~= nil then return ret end
  110. end
  111. end
  112. end