191 lines
4.0 KiB
Plaintext
Executable File
191 lines
4.0 KiB
Plaintext
Executable File
-- Rockstar XML parser
|
|
-- Rockstar North
|
|
-- 1/3/2005
|
|
-- by unknown
|
|
|
|
-- Basic XML parser
|
|
|
|
include "pipeline/util/string.ms"
|
|
|
|
-- XML element structure
|
|
struct xmlelement (name, entries, params)
|
|
|
|
--------------------------------------------------------------
|
|
-- read XML label
|
|
--------------------------------------------------------------
|
|
fn XMLParseLabel file attriblist = (
|
|
|
|
local label
|
|
|
|
if (skiptostring file "<") == undefined then (
|
|
|
|
label = undefined
|
|
) else (
|
|
|
|
label = readdelimitedstring file ">"
|
|
|
|
if label == undefined do throw "XML: Error parsing file"
|
|
|
|
labellist = RsFilter label " "
|
|
|
|
if labellist.count > 1 then (
|
|
|
|
for i = 2 to labellist.count do (
|
|
|
|
append attriblist labellist[i]
|
|
)
|
|
)
|
|
|
|
label = labellist[1]
|
|
)
|
|
|
|
label
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- parse XML child elements
|
|
--------------------------------------------------------------
|
|
fn XMLParseElements parentElement file = (
|
|
|
|
local label
|
|
local element
|
|
local pos
|
|
local entry
|
|
|
|
pos = filepos file
|
|
|
|
entry = readdelimitedstring file "<"
|
|
|
|
if (filterstring entry " \t\n").count != 0 do (
|
|
|
|
append parentElement.entries entry
|
|
)
|
|
|
|
seek file pos
|
|
|
|
attribs = #()
|
|
local quit = false
|
|
|
|
while ((quit == false) and ((label = XMLParseLabel file attribs) != undefined)) do (
|
|
|
|
-- found a comment
|
|
if label[1] != "!" then (
|
|
|
|
-- found an end element
|
|
if label[1] == "/" then (
|
|
|
|
quit = true
|
|
) else (
|
|
|
|
element = (xmlelement label #() attribs)
|
|
XMLParseElements element file
|
|
|
|
-- add to list of entries for parent element
|
|
append parentElement.entries element
|
|
|
|
attribs = #()
|
|
)
|
|
)
|
|
)
|
|
|
|
if quit == false then (
|
|
|
|
if (parentElement.name != "root") do throw "XML: Error parsing file"
|
|
)
|
|
|
|
true
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Parse XML file to create an XML element hierarchy
|
|
--------------------------------------------------------------
|
|
fn XMLParseFile filename checkheader:true = (
|
|
|
|
local file, line, rootelement
|
|
|
|
-- open file
|
|
file = openfile filename
|
|
if file == undefined do (
|
|
|
|
format "XML File: % not found. Aborting.\n" filename
|
|
return undefined
|
|
)
|
|
|
|
-- read first line
|
|
|
|
if checkheader then (
|
|
|
|
local line = readline file
|
|
if line != "<?xml version = \"1.0\"?>" and line != "<?xml version=\"1.0\"?>" and line != "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>"do (
|
|
|
|
format "XML Header check failed for %. Aborting.\n" filename
|
|
return undefined
|
|
)
|
|
)
|
|
|
|
rootelement = (xmlelement "root" #())
|
|
XMLParseElements rootelement file
|
|
|
|
close file
|
|
|
|
rootelement
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Find XML element
|
|
--------------------------------------------------------------
|
|
fn XMLGetElement parentElement name = (
|
|
|
|
local retval = undefined
|
|
lowername = RsLowercase(name)
|
|
|
|
for element in parentElement.entries do (
|
|
|
|
if retval == undefined then (
|
|
|
|
if (classof element) == xmlelement and RsLowercase(element.name) == lowername do (
|
|
|
|
retval = element
|
|
)
|
|
)
|
|
)
|
|
|
|
retval
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Find XML param
|
|
--------------------------------------------------------------
|
|
fn XMLGetParam parentElement name = (
|
|
|
|
retval = undefined
|
|
|
|
for param in parentElement.params do (
|
|
|
|
if retval == undefined then (
|
|
|
|
paramPair = RsFilter param "="
|
|
|
|
if paramPair.count > 1 and RsLowercase(paramPair[1]) == RsLowercase(name) then (
|
|
|
|
if paramPair[2].count > 2 and paramPair[2][1] == "\"" and paramPair[2][paramPair[2].count] == "\"" then (
|
|
|
|
retval = (substring paramPair[2] 2 (paramPair[2].count - 2))
|
|
) else (
|
|
|
|
retval = paramPair[2]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
retval
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Get XML entry
|
|
--------------------------------------------------------------
|
|
fn XMLGetEntry element = (
|
|
|
|
element.entries[1]
|
|
) |