From b67255cdc844b2eba9386da8f65ee5e18529d714 Mon Sep 17 00:00:00 2001 From: "jason.bray@faithlife.com" Date: Tue, 18 Apr 2023 14:30:38 -0400 Subject: [PATCH] Namespace declaration processed first. Issue 22 If a namespace is declared after an attribute that uses that namespace, the namespace should still be correctly identified. This code change causes any namespace declarations to be processed before other attributes. --- src/AngleSharp.Xml.Tests/Parser/XmlParsing.cs | 14 +++++++++++++ src/AngleSharp.Xml/Parser/XmlDomBuilder.cs | 20 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/AngleSharp.Xml.Tests/Parser/XmlParsing.cs b/src/AngleSharp.Xml.Tests/Parser/XmlParsing.cs index 1bf0f2e..af74c74 100644 --- a/src/AngleSharp.Xml.Tests/Parser/XmlParsing.cs +++ b/src/AngleSharp.Xml.Tests/Parser/XmlParsing.cs @@ -1,3 +1,7 @@ +using System.Linq; +using System.Threading.Tasks; +using AngleSharp.Dom; + namespace AngleSharp.Xml.Tests.Parser { using AngleSharp.Xml.Parser; @@ -146,5 +150,15 @@ public void ParseInvalidXmlShouldNotThrowWhenSuppressingErrors_Issue14() parser.ParseDocument(source); }); } + } + + [Test] + public async Task NamespaceDeclarationsInAttributesShouldNotCareAboutOrdering() + { + var document = @"1" + .ToXmlDocument(); + var root = document.DocumentElement; + Assert.AreEqual("http://www.idpf.org/2007/ops", + root.Attributes.First(att => att.LocalName == "type").NamespaceUri); } } diff --git a/src/AngleSharp.Xml/Parser/XmlDomBuilder.cs b/src/AngleSharp.Xml/Parser/XmlDomBuilder.cs index 728214d..d123e31 100644 --- a/src/AngleSharp.Xml/Parser/XmlDomBuilder.cs +++ b/src/AngleSharp.Xml/Parser/XmlDomBuilder.cs @@ -1,3 +1,5 @@ +using System.Linq; + namespace AngleSharp.Xml.Parser { using AngleSharp.Dom; @@ -274,9 +276,23 @@ private void InBody(XmlToken token) var element = CreateElement(tagToken.Name, tagToken.IsSelfClosing); CurrentNode.AppendChild(element); - for (var i = 0; i < tagToken.Attributes.Count; i++) + var namespaceDeclarations = tagToken.Attributes + .Where(attr => attr.Key.StartsWith("xmlns")) + .ToList(); + var otherAttributes = tagToken.Attributes + .Where(attr => !attr.Key.StartsWith("xmlns")) + .ToList(); + + for (var i = 0; i < namespaceDeclarations.Count; i++) + { + var attr = namespaceDeclarations[i]; + var item = CreateAttribute(attr.Key, attr.Value.Trim()); + element.AddAttribute(item); + } + + for (var i = 0; i < otherAttributes.Count; i++) { - var attr = tagToken.Attributes[i]; + var attr = otherAttributes[i]; var item = CreateAttribute(attr.Key, attr.Value.Trim()); element.AddAttribute(item); }