如何构造和编写XML文件?

时间:2013-05-06 05:25:07

标签: xml api utf-8 livecode

这个问题是关于将LiveCode堆栈中的XML数据写入文件。 用户指南的第6.7章讨论了LiveCode提供的XML函数。我正在寻找显示如何构造XML文件并将其写入磁盘文件的示例。

http://support.runrev.com/tutorials/xmldemo.rev.gz是关于如何使用LiveCode的revNNN XML函数的教程堆栈。

它有一个例子

  ....
  local tDocID, tParentNode, tSubNode

  -- get the document ID for the current XML tree
  put fld "DocID" into tDocID

  -- specify the root node for the XML tree
  put "/employeeTable" into tParentNode

  revAddXMLNode tDocID, tParentNode, "employee", ""
  put the result into tSubNode

  -- add the IDnum attribute to the newly created data record
  revSetXMLAttribute tDocID, tSubNode, "IDnum", "1"

  -- add the remaining data elements, checking for error after each addition
  revAddXMLNode tDocID, tSubNode, "firstName", "Steve"
  revAddXMLNode tDocID, tSubNode, "lastName", "Jobs"
  revAddXMLNode tDocID, tSubNode, "roomNum", "001"
  revAddXMLNode tDocID, tSubNode, "phoneExt", "345"
  revAddXMLNode tDocID, tSubNode, "parkingSlot", 100

结果

  <?xml version="1.0"?>
  <employeeTable>

    <employee IDnum="1">
    <firstName>Steve</firstName>
    <lastName>Jobs</lastName>
    <roomNum>001</roomNum>
    <phoneExt>345</phoneExt>
    <parkingSlot>100</parkingSlot>
    </employee>

 </employeeTable>

是否存在通过提供便利功能使编写XML文本更容易的库,以便在添加嵌套结构时不需要跟踪节点?

这样的东西
startXML "theEmployees.xml"  -- gives the file name 
startTag "employeetable"
  startTag "employee"
    addAttribute "IDnum", 1
    startTag "firstName"
      writeContent "Steve"
    closeTag
    -- or
    writeNode "lastname", "Jobs"
    writeNode "roomnum", "001"
    -- ....
   closeTag -- employee
closeTag -- employeeTable
closeXML

写这样的几个函数比较容易,但问题是。有没有确定的方法将XML文本写入LiveCode中的文件?

4 个答案:

答案 0 :(得分:1)

如果您只想编写XML(而不是创建revXMLTrees),您可以编写自己的函数。这对于首发来说如何:

local _tags
local _xml
local _level
local _tabs

function q pText
   return quote & pText & quote
end q

on startXML
   put "<?xml version=" & q("1.0") & "?>" & return into _xml
   put 0 into _level
   put empty into _tabs
   put empty into _tags
end startXML

on startTag pTag
   put _tabs & "<" & pTag & ">" & return after _xml
   add 1 to _level
   put pTag into _tags[_level]
   put tab after _tabs  
end startTag

on closeTag
   delete char 1 of _tabs
   put _tabs & "</" & _tags[_level] & ">" & return after _xml
   # Do a 'delete variable _tags[_level]' if you really want to clean the array as you go 
   subtract 1 from _level
end closeTag

on addAttribute pAttribute, pValue
   # This should go into the last tag, but as we have "proper XML" so far we can backtrace two chars (">" and newline)
   put space & pAttribute & "=" & q(pValue) before char -2 of _xml
end addAttribute

on writeContent pContent
   put _tabs & pContent & return after _xml
end writeContent

on writeNode pNode, pValue
   put _tabs & "<" & pNode & ">" & pValue & "</" & pNode & ">" & return after _xml
end writeNode

getProp xml
   return _xml
end xml

将该脚本放在卡片或堆叠上,然后就可以:

startXML
startTag "employeetable"
startTag "employee"
addAttribute "IDNum", 1
startTag "firstName"
writeContent "Steve"
closeTag
writeNode "lastName", "Jobs"
writeNode "roomnum", "001"
writeNode "phoneExt", "345"
writeNode "parkingSlot", "100"
closeTag
closeTag
put the xml of this card into field 1

这当然不是一个完整的解决方案,因为它不会对您的输入进行任何验证,并且格式可能不是您想要的,但我想它可以让您开始。

答案 1 :(得分:0)

Mark Wieder(公共域)的版本控制库包含一些可能被考虑的XML编写过程。

http://revonline2.runrev.com/stack/686/libVersionControl

--> xml

/** ------------------------------
* XML.StartTag
*
* Return <tag>
* Convert embedded commas and spaces as part of the process.
* ------------------------------
*/
private function XML.StartTag pTag
    if comma is in pTag then
        replace comma with kMagicComma in pTag
    end if
    if "&" is in pTag then
        replace "&" with kAmpersand in pTag
    end if
    if space is in pTag and "=" is not in pTag then
        replace space with kMagicSpace in pTag
    end if
    return "<" & pTag & ">"
end XML.StartTag

/** ------------------------------
* XML.EndTag
*
* Return </tag>
* Convert embedded commas and spaces as part of the process.
*
* @pTag : the tag of interest
* ------------------------------
*/
private function XML.EndTag pTag
   if comma is in pTag then
      replace comma with kMagicComma in pTag
   end if
   if space is in pTag and "=" is not in pTag then
      replace space with kMagicSpace in pTag
   end if
   return "</" & pTag & ">" & cr
end XML.EndTag

/** ------------------------------
* XML.Element
*
* return <tag>value</tab>
* base64encode the value item if necessary
* ------------------------------
*/
private function XML.Element pTag, pValue
    local tIsBinary
    local tTest

    put false into tIsBinary
    if pTag is in "htmlText, script, imagedata" then
        put true into tIsBinary
    else
        repeat for each byte tByte in pValue
            put chartonum(tByte) into tTest
            -- see if the char is printable
            if tTest < 32 or tTest > 128 then
                put true into tIsBinary
                -- no need to look further
                exit repeat
            end if
        end repeat
    end if
    -- can't have binary data in xml
    if tIsBinary then
        put "base64decode(" && q(base64encode(pValue)) && ")" into pValue
    end if
    return XML.StartTag(pTag) & pValue & XML.EndTag(pTag)
end XML.Element

--> Utilities

function q pText
    return quote & pText & quote
end q

答案 2 :(得分:0)

LiveCode文档(字典)包含许多与XML相关的功能。这些函数足以导航和操作任何XML树。但是,XML external不能很好地处理索引,这意味着您需要自己跟踪这些索引。例如。您可以使用索引号循环遍历XML树,检查每个树节点的ID号,并使用具有正确ID号的节点。如果您需要一个例子,请告诉我。

对于其他一切,弄清楚库是如何工作的,就像弄清楚XML函数本身一样复杂。只需阅读内置文档。

答案 3 :(得分:0)

它接缝它不适用于UTF8文本(重音字符,如ąęćś)作为节点值。