Skip to content

Reset default NS test and partial fix#7

Draft
hanshuebner wants to merge 2 commits intolunarmodules:mainfrom
hanshuebner:reset-default-ns
Draft

Reset default NS test and partial fix#7
hanshuebner wants to merge 2 commits intolunarmodules:mainfrom
hanshuebner:reset-default-ns

Conversation

@hanshuebner
Copy link
Copy Markdown

As discussed on Slack

Hans Hübner added 2 commits October 6, 2022 16:00
This ensures that the default namespace can be reset in documents.
@Tieske
Copy link
Copy Markdown
Member

Tieske commented Jul 30, 2024

slack discussion:

@hanshuebner
I've run into a bug in expadom that I find difficult to fix:

local expadom = require "expadom"

local xml = [[
<foo xmlns="http://example.com/">
  <bar xmlns="">
    <baz/>
  </bar>
</foo>
]]
local doc = assert(expadom.parseDocument(xml))
print(xml)
print(table.concat(doc:write()))

The output is

<?xml version="1.0" encoding="UTF-8" ?>
<foo xmlns="http://example.com/">
  <bar>
    <baz/>
  </bar>
</foo>

expadom incorrectly renders the bar element to be in the http://example.com/ namespace even though the default namespace has been reset on that element in the input file. This breaks some of the c14n test cases so it needs to be fixed. Maybe you can guide me on this or you can quickly determine the cause for the misbehavior? I think it is not a LuaExapat problem as the element is correctly passed to StartElement without a namespace:

		StartElement = function(parser, elementName, attributes)
			local ctx = context_cache[parser]
			local doc = ctx.doc
			local qualifiedName, namespaceURI = split(elementName)

			-- attach defined explicit namespaces on this element
			local explicitNamespaces = ctx.explicitNamespaces
			ctx.explicitNamespaces = {}
			
			local elem
			if namespaceURI then
				elem = assert(doc:createElementNS(namespaceURI, qualifiedName))
				local prefix = elem.__prop_values.prefix
				explicitNamespaces[prefix or DEFAULT_NS_KEY] = nil -- remove since it's implicit
			else
				elem = assert(doc:createElement(qualifiedName))
			end

It seems that if no namespace is attached to the element, the current namespace is used by the way of the context? But I'm not sure. Any ideas?

@Tieske
is xmlns="" allowed?

@hanshuebner
Yes. It is used to reset the default namespace to "none".
(It cannot be used on prefixes though)

Maybe this?

		StartElement = function(parser, elementName, attributes)
			local ctx = context_cache[parser]
			local doc = ctx.doc
			local qualifiedName, namespaceURI = split(elementName)

			-- attach defined explicit namespaces on this element
			local explicitNamespaces = ctx.explicitNamespaces
			ctx.explicitNamespaces = {}

			local elem
			elem = assert(doc:createElementNS(namespaceURI or "", qualifiedName))
			local prefix = elem.__prop_values.prefix
			explicitNamespaces[prefix or DEFAULT_NS_KEY] = nil -- remove since it's implicit

i.e. never use createElement ?

It breaks a lot of tests though because it then incorrectly renders xmlns="" into every top-level element that does not have an explicit namespace defined.

@Tieske
Can you for now create a PR with a test case that fails?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants