Как создать и написать файл XML?

Этот вопрос касается записи данных XML из стека LiveCode в файл. В главе 6.7 руководства пользователя рассказывается о XML-функциях, предоставляемых LiveCode. Я ищу примеры, которые показывают, как создать файл XML и записать его в файл на диске.

http://support.runrev.com/tutorials/xmldemo.rev.gz представляет собой обучающий стек о том, как использовать XML-функции revNNN LiveCode.

У него есть пример

  ....
  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?


person z--    schedule 06.05.2013    source источник
comment
Это библиотека управления версиями Марка Видера (общественное достояние), содержащая некоторые процедуры записи XML. revonline2.runrev.com/stack/686/libVersionControl   -  person z--    schedule 06.05.2013
comment
В моей книге Programming LiveCode for the Real Beginner есть глава о создании и чтении файлов XML.   -  person Mark    schedule 15.06.2013


Ответы (4)


Если вы просто хотите писать XML (а не создавать revXMLTree), вы можете написать свои собственные функции. Как насчет этого для начала:

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

Это, конечно, не полное решение, так как оно не будет проверять ваш ввод, и формат может быть не совсем тем, что вы хотите, но я думаю, что это может помочь вам начать работу.

person hliljegren    schedule 08.05.2013
comment
Да, это то, к чему я стремлюсь. Спасибо. Я продолжу эту реализацию и проведу несколько тестов. Потом выложу результат. - person z--; 08.05.2013

Библиотека управления версиями Марка Видера (общественное достояние) содержит некоторые процедуры записи 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
person z--    schedule 06.05.2013
comment
Я должен добавить, что, хотя мне проще использовать такие функции для создания файлов xml, чем использовать встроенные функции, встроенные процедуры очень удобны для чтения и анализа файлов xml. - person mwieder; 06.05.2013
comment
Да, я ищу функции LiveCode для написания XML. - person z--; 07.05.2013

Документация LiveCode (словарь) содержит множество функций, связанных с XML. Этих функций достаточно для навигации по любому XML-дереву и управления им. Однако внешний XML не очень хорошо обрабатывает индексы, а это значит, что вам нужно следить за ними самостоятельно. Например. вы можете прокручивать XML-дерево, используя их порядковый номер, проверять идентификационный номер каждого узла дерева и использовать узел с правильным идентификационным номером. Дайте мне знать, если вам нужен пример.

Во всем остальном понять, как работает библиотека, так же сложно, как понять сами функции XML. Просто прочитайте встроенную документацию.

person Mark    schedule 07.05.2013
comment
Я привел пример, как выглядит такой API для записи XML в вопросе. Я прошу простых способов создания файла XML. Смотрите мой другой ответ. Пример для Java приведен здесь java.ociweb.com/mark/programming/wax.html< /а> . ‹citation›Построение структуры DOM для описания большого XML-документа не сработает, потому что он не помещается в памяти. Даже если бы это было так, это не простой API. ‹/citation› - person z--; 07.05.2013

Похоже, он не будет работать с текстом UTF8 (символы с диакритическими знаками, такими как ąęćś) в качестве значений узлов.

person Marek Niesiobędzki    schedule 07.05.2013
comment
как вы думаете, не работает с UTF8? Функции revNNN? - person z--; 07.05.2013
comment
Я думаю о функциях writeContent и addAttribute. - person Marek Niesiobędzki; 19.05.2013
comment
Просто конвертируйте файл с помощью uniDecode(uniEncode(myXMLData,UTF8)). - person Mark; 15.06.2013