Skip to content

Commit

Permalink
Generate XML for array of nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
eraserhd authored and Corey Johnson committed Mar 6, 2011
1 parent 23fef0a commit b2345bf
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
43 changes: 37 additions & 6 deletions lib/extensions/xml/wax_xml.m
Expand Up @@ -202,6 +202,29 @@ static void createAttributes(lua_State *L, xmlNodePtr node) {
}
}

static BOOL isNumericIndexedArray(lua_State *L, int idx) {
BOOL isArray = NO;
if (lua_istable(L, idx)) {
lua_pushnil(L);
if (lua_next(L, idx-1)) {
isArray = (lua_isnumber(L, -2) && lua_tointeger(L, -2) == 1);
lua_pop(L, 2);
}
}
return isArray;
}

static void createXML(lua_State *L, xmlDocPtr doc, xmlNodePtr node, char *textLabel, char *attrsLabel);

static void createElement(lua_State *L, xmlDocPtr doc, xmlNodePtr node, const char *name, char *textLabel, char *attrsLabel) {
xmlNodePtr childNode = xmlNewNode(NULL, BAD_CAST name);
xmlAddChild(node, childNode);
createXML(L, doc, childNode, textLabel, attrsLabel);

if (!node) // Root node.
xmlDocSetRootElement(doc, childNode);
}

static void createXML(lua_State *L, xmlDocPtr doc, xmlNodePtr node, char *textLabel, char *attrsLabel) {
if (lua_isstring(L, -1)) { // Could just be a string. If so, just set the text of the node
xmlNodePtr textNode = xmlNewText(BAD_CAST lua_tostring(L, -1));
Expand All @@ -221,12 +244,21 @@ static void createXML(lua_State *L, xmlDocPtr doc, xmlNodePtr node, char *textLa
createAttributes(L, node);
}
else {
xmlNodePtr childNode = xmlNewNode(NULL, BAD_CAST name);
xmlAddChild(node, childNode);
createXML(L, doc, childNode, textLabel, attrsLabel);

if (isNumericIndexedArray(L, -1)) {
lua_pushnil(L);
while (lua_next(L, -2)) {
createElement(L, doc, node, name, textLabel, attrsLabel);
if (!node) { // Ignore duplicate root nodes
lua_pop(L, 2);
break;
}
lua_pop(L, 1);
}
}
else {
createElement(L, doc, node, name, textLabel, attrsLabel);
}
if (!node) { // Root node. Ignore other root nodes
xmlDocSetRootElement(doc, childNode);
lua_pop(L, 2); // remove the value and the key
break;
}
Expand All @@ -236,7 +268,6 @@ static void createXML(lua_State *L, xmlDocPtr doc, xmlNodePtr node, char *textLa
}
}


static int generate(lua_State *L) {
BEGIN_STACK_MODIFY(L);

Expand Down
26 changes: 16 additions & 10 deletions tools/Tests/scripts/tests/xmlTest.lua
Expand Up @@ -97,15 +97,21 @@ describe["XML generating"] = function()
expect(result:find("xmlns:my=\"http://wtf.org\"")).should_not_be(nil)
expect(result:find("my:cool=\"yes\"")).should_not_be(nil)
end
--
-- it["generates nested elements with the same name as an array"] = function()
-- local result = wax.xml.parse("<names><name>corey</name><name>bob</name><name>phill</name></names>")
-- expect(type(result.names.name)).should_be("table")
-- expect(#result.names.name).should_be(3)
-- expect(result.names.name[1].text).should_be("corey")
-- expect(result.names.name[2].text).should_be("bob")
-- expect(result.names.name[3].text).should_be("phill")
-- end

it["generates multiple elements from an array"] = function()
local result = removeDeclaration(
{names =
{name = {
{ text = "corey" },
{ text = "bob" },
{ text = "phill" }
}}})
expect(result:find("<name>corey</name>")).should_not_be(nil)
expect(result:find("<name>bob</name>")).should_not_be(nil)
expect(result:find("<name>phill</name>")).should_not_be(nil)
expect(result:find("<names><name>")).should_not_be(nil)
expect(result:find("</name></names>")).should_not_be(nil)
end

it["generates elements named text (with optional names specified)"] = function()
local result = removeDeclaration(
Expand All @@ -126,4 +132,4 @@ describe["XML generating"] = function()

expect(result).should_be("<word name=\"works\"><attrs>inside</attrs></word>")
end
end
end

0 comments on commit b2345bf

Please sign in to comment.