Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset default NS test and partial fix #7

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

hanshuebner
Copy link

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
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