summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-11-15 19:54:35 +0800
committerruki <[email protected]>2025-11-15 19:57:22 +0800
commit9c8f2febdddbe6e1ca4f6e04d4ba0d6f4f0f364f (patch)
tree2e05c85af37a48ed39d7cd3b38171f9dd70b6282
parent48159a7a047aabcd77a4edb4cc98b6ecf3c51039 (diff)
use string apis
-rw-r--r--tests/modules/xml/test.lua13
-rw-r--r--xmake/core/base/xml.lua42
2 files changed, 35 insertions, 20 deletions
diff --git a/tests/modules/xml/test.lua b/tests/modules/xml/test.lua
index e7266c919..985600a9d 100644
--- a/tests/modules/xml/test.lua
+++ b/tests/modules/xml/test.lua
@@ -155,3 +155,16 @@ function test_find_update(t)
t:are_equal(encoded, '<root><item id="a" lang="en">bar</item><item id="b"/><item id="c">baz</item></root>')
end
+function test_decode_trim_text(t)
+ local doc = xml.decode("<root> foo </root>")
+ t:are_equal(xml.text_of(doc), " foo ")
+ local trimmed = xml.decode("<root> foo </root>", {trim_text = true})
+ t:are_equal(xml.text_of(trimmed), "foo")
+ local formatted = "<root>\n <item/>\n</root>"
+ local default = xml.decode(formatted)
+ t:are_equal(#default.children, 1)
+ local keep_ws = xml.decode(formatted, {keep_whitespace_nodes = true})
+ t:are_equal(#keep_ws.children, 3)
+ t:are_equal(keep_ws.children[1].kind, "text")
+end
+
diff --git a/xmake/core/base/xml.lua b/xmake/core/base/xml.lua
index 25c43423d..beb3a2ed4 100644
--- a/xmake/core/base/xml.lua
+++ b/xmake/core/base/xml.lua
@@ -22,9 +22,10 @@
local xml = xml or {}
-- load modules
-local io = require("base/io")
-local os = require("base/os")
-local table = require("base/table")
+local io = require("base/io")
+local os = require("base/os")
+local table = require("base/table")
+local string = require("base/string")
-- XML node structure (mutable DOM-style tables):
-- {
@@ -90,11 +91,6 @@ function xml._parse_attrs(attrstr)
return attrs
end
--- trim helper
-function xml._trim(str)
- return (str:gsub("^%s+", ""):gsub("%s+$", ""))
-end
-
-- iterate element children and optional prolog nodes
function xml._each_child(node, callback)
if not node or not callback then
@@ -168,7 +164,7 @@ function xml._parse_xpath(path)
end
i = i + 1
end
- local segment = xml._trim(path:sub(start, i - 1))
+ local segment = path:sub(start, i - 1):trim()
if segment ~= "" then
local step = xml._parse_xpath_segment(segment, axis)
table.insert(steps, step)
@@ -182,7 +178,7 @@ end
function xml._parse_xpath_segment(segment, axis)
local step = {axis = axis or "child", predicates = {}}
local name = segment:gsub("%b[]", "")
- name = xml._trim(name)
+ name = name:trim()
if name == "" or name == "*" then
step.node_test = "any"
elseif name == "." then
@@ -200,7 +196,7 @@ function xml._parse_xpath_segment(segment, axis)
step.name = name
end
for predicate in segment:gmatch("%b[]") do
- local expr = xml._trim(predicate:sub(2, -2))
+ local expr = predicate:sub(2, -2):trim()
if expr ~= "" then
local number_index = tonumber(expr)
if number_index then
@@ -307,14 +303,18 @@ end
-- append normalized text node to top element on stack
function xml._append_text(stack, text, opt)
opt = opt or {}
- if opt.trim_text ~= false then
- text = text:gsub("^%s+", ""):gsub("%s+$", "")
+ if opt.trim_text then
+ text = string.trim(text)
end
- if text ~= "" then
- local top = stack[#stack]
- top.children = top.children or {}
- table.insert(top.children, xml.text(xml._decode_entities(text)))
+ if text == "" then
+ return
end
+ if not opt.keep_whitespace_nodes and text:match("^%s*$") then
+ return
+ end
+ local top = stack[#stack]
+ top.children = top.children or {}
+ table.insert(top.children, xml.text(xml._decode_entities(text)))
end
-- ensure closing tag matches stack and pop it
@@ -465,7 +465,7 @@ end
-- e.g. `local doc, err = xml.decode("<root><item>foo</item></root>")`
--
-- @param data xml string
--- @param opt options (trim_text, etc.)
+-- @param opt options (e.g. {trim_text = true} to strip leading/trailing text, keep_whitespace_nodes = true)
-- @return root node or list on success, nil + error on failure
--
function xml.decode(data, opt)
@@ -585,7 +585,9 @@ function xml.decode(data, opt)
local prolog = {}
for _, child in ipairs(root_children) do
if child ~= rootnode then
- table.insert(prolog, child)
+ if not (child.kind == "text" and (child.text or ""):match("^%s*$")) then
+ table.insert(prolog, child)
+ end
end
end
if #prolog > 0 then
@@ -600,7 +602,7 @@ end
--
-- @param data xml string
-- @param callback function(node) -> true|false (return false to stop scanning)
--- @param opt options (trim_text, etc.)
+-- @param opt options (e.g. {trim_text = true}, {keep_whitespace_nodes = true})
-- @return true on success or nil, error on failure
--
function xml.scan(data, callback, opt)