Hallucinate some xml helper functions in lua

This commit is contained in:
2025-12-19 11:42:39 +01:00
parent fff8869aff
commit f1ea0f9156
2 changed files with 268 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
dofile("luahelper.lua")
-- Test cases for XML helper functions
-- Mock XML structure for testing
local testXML = {
_tag = "root",
_attr = {version = "1.0"},
_children = {
{
_tag = "item",
_attr = {name = "sword", damage = "10", weight = "5.5"},
_text = "Iron Sword"
},
{
_tag = "item",
_attr = {name = "shield", defense = "8"},
_children = {
{
_tag = "material",
_attr = {type = "steel", durability = "100"}
}
}
},
{
_tag = "container",
_children = {
{_tag = "item", _attr = {name = "potion", healing = "20"}},
{_tag = "item", _attr = {name = "scroll"}}
}
}
}
}
print("=== XML Helper Functions Tests ===\n")
-- Test findElements
print("1. Find all 'item' elements:")
local items = findElements(testXML, "item")
print(" Found " .. #items .. " items")
for i, item in ipairs(items) do
print(" - " .. (item._attr.name or "unnamed"))
end
-- Test getNumAttr and setNumAttr
print("\n2. Get/Set numeric attributes:")
local sword = items[1]
local damage = getNumAttr(sword, "damage")
print(" Sword damage: " .. tostring(damage))
setNumAttr(sword, "damage", damage * 2)
print(" After doubling: " .. sword._attr.damage)
-- Test modifyNumAttr
print("\n3. Modify numeric attribute:")
modifyNumAttr(sword, "weight", function(val) return val * 1.5 end)
print(" Sword weight modified: " .. sword._attr.weight)
-- Test filterElements
print("\n4. Filter elements with 'healing' attribute:")
local healingItems = filterElements(testXML, function(elem)
return hasAttr(elem, "healing")
end)
print(" Found " .. #healingItems .. " healing items")
-- Test visitElements
print("\n5. Visit all elements:")
local count = 0
visitElements(testXML, function(elem, depth, path)
count = count + 1
if depth <= 2 then
print(" " .. string.rep(" ", depth) .. elem._tag .. " @ " .. path)
end
end)
print(" Total elements visited: " .. count)
-- Test getText and setText
print("\n6. Text content:")
print(" Original text: " .. (getText(sword) or "none"))
setText(sword, "Modified Sword")
print(" New text: " .. getText(sword))
-- Test hasAttr and getAttr
print("\n7. Check attributes:")
print(" Sword has 'damage': " .. tostring(hasAttr(sword, "damage")))
print(" Sword has 'magic': " .. tostring(hasAttr(sword, "magic")))
print(" Sword name: " .. (getAttr(sword, "name") or "none"))
print("\n=== Tests Complete ===")

View File

@@ -350,3 +350,184 @@ function isArray(t)
end
modified = false
-- ============================================================================
-- XML HELPER FUNCTIONS
-- ============================================================================
--- Find all elements with a specific tag name (recursive search)
--- @param root table The root XML element (with _tag, _attr, _children fields)
--- @param tagName string The tag name to search for
--- @return table Array of matching elements
function findElements(root, tagName)
local results = {}
local function search(element)
if element._tag == tagName then
table.insert(results, element)
end
if element._children then
for _, child in ipairs(element._children) do
search(child)
end
end
end
search(root)
return results
end
--- Visit all elements recursively and call a function on each
--- @param root table The root XML element
--- @param callback function Function to call with each element: callback(element, depth, path)
function visitElements(root, callback)
local function visit(element, depth, path)
callback(element, depth, path)
if element._children then
for i, child in ipairs(element._children) do
local childPath = path .. "/" .. child._tag .. "[" .. i .. "]"
visit(child, depth + 1, childPath)
end
end
end
visit(root, 0, "/" .. root._tag)
end
--- Get numeric value from XML element attribute
--- @param element table XML element with _attr field
--- @param attrName string Attribute name
--- @return number|nil The numeric value or nil if not found/not numeric
function getNumAttr(element, attrName)
if not element._attr then return nil end
local value = element._attr[attrName]
if not value then return nil end
return tonumber(value)
end
--- Set numeric value to XML element attribute
--- @param element table XML element with _attr field
--- @param attrName string Attribute name
--- @param value number Numeric value to set
function setNumAttr(element, attrName, value)
if not element._attr then
element._attr = {}
end
element._attr[attrName] = tostring(value)
end
--- Modify numeric attribute by applying a function
--- @param element table XML element
--- @param attrName string Attribute name
--- @param func function Function that takes current value and returns new value
--- @return boolean True if modification was made
function modifyNumAttr(element, attrName, func)
local current = getNumAttr(element, attrName)
if current then
setNumAttr(element, attrName, func(current))
return true
end
return false
end
--- Find all elements matching a predicate function
--- @param root table The root XML element
--- @param predicate function Function that takes element and returns true/false
--- @return table Array of matching elements
function filterElements(root, predicate)
local results = {}
visitElements(root, function(element)
if predicate(element) then
table.insert(results, element)
end
end)
return results
end
--- Get text content of an element
--- @param element table XML element
--- @return string|nil The text content or nil
function getText(element)
return element._text
end
--- Set text content of an element
--- @param element table XML element
--- @param text string Text content to set
function setText(element, text)
element._text = text
end
--- Check if element has an attribute
--- @param element table XML element
--- @param attrName string Attribute name
--- @return boolean True if attribute exists
function hasAttr(element, attrName)
return element._attr and element._attr[attrName] ~= nil
end
--- Get attribute value as string
--- @param element table XML element
--- @param attrName string Attribute name
--- @return string|nil The attribute value or nil
function getAttr(element, attrName)
if not element._attr then return nil end
return element._attr[attrName]
end
--- Set attribute value
--- @param element table XML element
--- @param attrName string Attribute name
--- @param value any Value to set (will be converted to string)
function setAttr(element, attrName, value)
if not element._attr then
element._attr = {}
end
element._attr[attrName] = tostring(value)
end
-- ============================================================================
-- JSON HELPER FUNCTIONS
-- ============================================================================
--- Recursively visit all values in a JSON structure
--- @param data table JSON data (nested tables)
--- @param callback function Function called with (value, key, parent)
function visitJSON(data, callback)
local function visit(obj, key, parent)
callback(obj, key, parent)
if type(obj) == "table" then
for k, v in pairs(obj) do
visit(v, k, obj)
end
end
end
visit(data, nil, nil)
end
--- Find all values in JSON matching a predicate
--- @param data table JSON data
--- @param predicate function Function that takes (value, key, parent) and returns true/false
--- @return table Array of matching values
function findInJSON(data, predicate)
local results = {}
visitJSON(data, function(value, key, parent)
if predicate(value, key, parent) then
table.insert(results, value)
end
end)
return results
end
--- Modify all numeric values in JSON matching a condition
--- @param data table JSON data
--- @param predicate function Function that takes (value, key, parent) and returns true/false
--- @param modifier function Function that takes current value and returns new value
function modifyJSONNumbers(data, predicate, modifier)
visitJSON(data, function(value, key, parent)
if type(value) == "number" and predicate(value, key, parent) then
if parent and key then
parent[key] = modifier(value)
end
end
end)
end