Skip to content

Commit

Permalink
Remove namespace() post-callback, properly handling <foo xmlns='bar'/>
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin Kistner committed Feb 18, 2013
1 parent ffe2026 commit bb0c109
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 22 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ is syntactically-invalid (not well-formed) to be parsed without reporting an err
text = function(text) end, -- text and CDATA nodes
comment = function(content) end, -- comments
pi = function(target,content) end, -- processing instructions e.g. "<?yes mon?>"
namespace = function(nsURI) end, -- when xmlns="..." is seen (after startElement)
}

-- Ignore whitespace-only text nodes and strip leading/trailing whitespace from text
Expand Down Expand Up @@ -146,6 +145,10 @@ In this case no table will have a `parent` attribute, elements will not have the

## History

### v0.5.1 2013-Feb-18
+ `<foo xmlns="bar">` now directly generates `startElement("foo","bar")`
with no post callback for `namespace` required.

### v0.5 2013-Feb-18
+ Use the `local SLAXML=require 'slaxml'` pattern to prevent any pollution
of the global namespace.
Expand Down
3 changes: 0 additions & 3 deletions slaxdom.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ function SLAXML:dom(xml,opts)
current = el
push(stack,el)
end,
namespace = function(nsURI)
current.nsURI = nsURI
end,
attribute = function(name,value,nsURI)
if not current or current.type~="element" then error(("Encountered an attribute %s=%s but I wasn't inside an element"):format(name,value)) end
local attr = {type='attribute',name=name,nsURI=nsURI,value=value,parent=rich and current or nil}
Expand Down
41 changes: 23 additions & 18 deletions slaxml.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
--[=====================================================================[
v0.5 Copyright © 2013 Gavin Kistner <[email protected]>; MIT Licensed
v0.5.1 Copyright © 2013 Gavin Kistner <[email protected]>; MIT Licensed
See http://github.com/Phrogz/SLAXML for details.
--]=====================================================================]
local SLAXML = {
VERSION = "0.5",
VERSION = "0.5.1",
_call = {
pi = function(target,content)
print(string.format("<?%s %s?>",target,content))
Expand All @@ -23,9 +23,6 @@ local SLAXML = {
closeElement = function(name,nsURI)
print(string.format("</%s>",name))
end,
namespace = function(nsURI) -- applies a default namespace to the current element
print(string.format(" (xmlns=%s)",nsURI))
end,
}
}

Expand All @@ -42,7 +39,9 @@ function SLAXML:parse(xml,options)
local pos = 1
local state = "text"
local textStart = 1
local currentElement
local currentElement={}
local currentAttributes={}
local currentAttributeCt
local nsStack = {}

local entityMap = { ["lt"]="<", ["gt"]=">", ["amp"]="&", ["quot"]='"', ["apos"]="'" }
Expand Down Expand Up @@ -91,20 +90,20 @@ function SLAXML:parse(xml,options)
local function startElement()
first, last, match1 = find( xml, '^<([%a_][%w_.-]*)', pos )
if first then
nsURI = nil
currentElement[2] = nil
finishText()
pos = last+1
first,last,match2 = find(xml, '^:([%a_][%w_.-]*)', pos )
if first then
nsURI = nsForPrefix(match1)
currentElement = match2
currentElement[1] = match2
currentElement[2] = nsForPrefix(match1)
match1 = match2
pos = last+1
else
currentElement = match1
for i=#nsStack,1,-1 do if nsStack[i]['!'] then nsURI = nsStack[i]['!']; break end end
currentElement[1] = match1
for i=#nsStack,1,-1 do if nsStack[i]['!'] then currentElement[2] = nsStack[i]['!']; break end end
end
if self._call.startElement then self._call.startElement(match1,nsURI) end
currentAttributeCt = 0
push(nsStack,{})
return true
end
Expand All @@ -127,22 +126,23 @@ function SLAXML:parse(xml,options)
end
end
if match1 and match2 then
nsURI = nil
local currentAttribute = {match1,match2}
local prefix,name = string.match(match1,'^([^:]+):([^:]+)$')
if prefix then
if prefix=='xmlns' then
nsStack[#nsStack][name] = match2
else
nsURI = nsForPrefix(prefix)
match1 = name
currentAttribute[1] = name
currentAttribute[3] = nsForPrefix(prefix)
end
else
if match1=='xmlns' then
nsStack[#nsStack]['!'] = match2
if self._call.namespace then self._call.namespace(match2) end
currentElement[2] = match2
end
end
if self._call.attribute then self._call.attribute(match1,match2,nsURI) end
currentAttributeCt = currentAttributeCt + 1
currentAttributes[currentAttributeCt] = currentAttribute
return true
end
end
Expand All @@ -164,9 +164,14 @@ function SLAXML:parse(xml,options)
state = "text"
pos = last+1
textStart = pos

if self._call.startElement then self._call.startElement(unpack(currentElement)) end
if self._call.attribute then
for i=1,currentAttributeCt do self._call.attribute(unpack(currentAttributes[i])) end end

if match1=="/" then
pop(nsStack)
if self._call.closeElement then self._call.closeElement(currentElement) end
if self._call.closeElement then self._call.closeElement(unpack(currentElement)) end
end
return true
end
Expand Down

0 comments on commit bb0c109

Please sign in to comment.