Skip to content

Commit a6391ae

Browse files
authored
Merge pull request #63 from evolvedbinary/6.x.x/hotfix/xml-prefix-serialization
[6.x.x] Fixes to namespace prefix coalescence
2 parents 18413ce + 5f122c3 commit a6391ae

File tree

3 files changed

+114
-3
lines changed

3 files changed

+114
-3
lines changed

exist-core/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@
701701
<include>src/main/java/org/exist/util/JREUtil.java</include>
702702
<include>src/main/java/org/exist/util/OSUtil.java</include>
703703
<include>src/main/java/org/exist/util/StringUtil.java</include>
704+
<include>src/test/java/org/exist/util/serializer/SAXSerializerTest.java</include>
704705
<include>src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml</include>
705706
<include>src/test/java/org/exist/xquery/ImportFromPkgTest.java</include>
706707
<include>src/main/java/org/exist/xquery/JavaBinding.java</include>
@@ -1322,6 +1323,7 @@
13221323
<exclude>src/main/java/org/exist/util/serializer/EXISerializer.java</exclude>
13231324
<exclude>src/test/java/org/exist/util/serializer/HTML5WriterTest.java</exclude>
13241325
<exclude>src/main/java/org/exist/util/serializer/SAXSerializer.java</exclude>
1326+
<exclude>src/test/java/org/exist/util/serializer/SAXSerializerTest.java</exclude>
13251327
<exclude>src/main/java/org/exist/util/serializer/SerializerObjectFactory.java</exclude>
13261328
<exclude>src/main/java/org/exist/util/serializer/json/JSONObject.java</exclude>
13271329
<exclude>src/test/java/org/exist/util/serializer/json/JSONObjectTest.java</exclude>

exist-core/src/main/java/org/exist/util/serializer/SAXSerializer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public void startElement(final QName qname, final AttrList attribs) throws SAXEx
317317
for (final Map.Entry<String, String> nsEntry : optionalNamespaceDecls.entrySet()) {
318318
final String prefix = nsEntry.getKey();
319319
final String uri = nsEntry.getValue();
320-
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && elemPrefix.equals(prefix))) {
320+
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && StringUtil.equals(qname.getPrefix(), prefix))) {
321321
receiver.namespace(prefix, uri);
322322
}
323323
}
@@ -328,7 +328,7 @@ public void startElement(final QName qname, final AttrList attribs) throws SAXEx
328328
}
329329
final String uri = nsEntry.getValue();
330330
if(!optionalNamespaceDecls.containsKey(prefix)) {
331-
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && elemPrefix.equals(prefix))) {
331+
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && StringUtil.equals(qname.getPrefix(), prefix))) {
332332
receiver.namespace(prefix, uri);
333333
}
334334
}
@@ -400,7 +400,7 @@ public void endElement(final QName qname) throws SAXException {
400400
if (enforceXHTML && elemPrefix.isEmpty() && namespaceURI.isEmpty()) {
401401
namespaceURI = Namespaces.XHTML_NS;
402402
}
403-
receiver.endElement(new QName(qname.getLocalPart(), namespaceURI, qname.getPrefix()));
403+
receiver.endElement(new QName(qname.getLocalPart(), namespaceURI, elemPrefix));
404404

405405
receiver.setDefaultNamespace(nsSupport.getURI(XMLConstants.DEFAULT_NS_PREFIX));
406406
} catch (final TransformerException e) {
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
package org.exist.util.serializer;
22+
23+
import org.apache.commons.io.output.StringBuilderWriter;
24+
import org.exist.dom.QName;
25+
import org.junit.jupiter.api.Test;
26+
import org.xml.sax.SAXException;
27+
28+
import javax.xml.transform.OutputKeys;
29+
import java.util.Properties;
30+
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
33+
/**
34+
* SAX Serialization tests to check for:
35+
* <a href="https://github.com/eXist-db/exist/issues/5790">eXist-db issue #5790</a>
36+
* <a href="https://github.com/evolvedbinary/elemental/issues/61">Elemental issue #61</a>
37+
*
38+
* @author <a href="mailto:[email protected]">Adam Retter</a>
39+
*/
40+
public class SAXSerializerTest {
41+
42+
private static final Properties OUTPUT_PROPERTIES = new Properties();
43+
static {
44+
OUTPUT_PROPERTIES.put(OutputKeys.INDENT, "no");
45+
OUTPUT_PROPERTIES.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
46+
}
47+
48+
@Test
49+
public void coalesceNamespacePrefixesFromStrings() throws SAXException {
50+
try (final StringBuilderWriter writer = new StringBuilderWriter()) {
51+
final SAXSerializer saxSerializer = new SAXSerializer(writer, OUTPUT_PROPERTIES);
52+
53+
saxSerializer.startDocument();
54+
saxSerializer.startElement("http://exist-db.org/xquery/repo", "meta", "meta", null);
55+
saxSerializer.startElement("http://exist-db.org/xquery/repo", "changelog", "changelog", null);
56+
57+
saxSerializer.startElement("http://exist-db.org/xquery/repo", "change", "change", null);
58+
saxSerializer.endElement("http://exist-db.org/xquery/repo", "change", "change");
59+
60+
saxSerializer.startElement("http://exist-db.org/xquery/repo", "change", "change", null);
61+
saxSerializer.characters("change-text-1");
62+
saxSerializer.endElement("http://exist-db.org/xquery/repo", "change", "change");
63+
64+
saxSerializer.startElement("http://exist-db.org/xquery/repo", "change", "repo:change", null);
65+
saxSerializer.endElement("http://exist-db.org/xquery/repo", "change", "repo:change");
66+
67+
saxSerializer.startElement("http://exist-db.org/xquery/repo", "change", "repo:change", null);
68+
saxSerializer.characters("change-text-2");
69+
saxSerializer.endElement("http://exist-db.org/xquery/repo", "change", "repo:change");
70+
71+
saxSerializer.endElement("http://exist-db.org/xquery/repo", "changelog", "changelog");
72+
saxSerializer.endElement("http://exist-db.org/xquery/repo", "meta", "meta");
73+
saxSerializer.endDocument();
74+
75+
assertEquals("<meta xmlns=\"http://exist-db.org/xquery/repo\"><changelog><change/><change>change-text-1</change><change/><change>change-text-2</change></changelog></meta>", writer.toString());
76+
}
77+
}
78+
79+
@Test
80+
public void coalesceNamespacePrefixesFromQName() throws SAXException {
81+
try (final StringBuilderWriter writer = new StringBuilderWriter()) {
82+
final SAXSerializer saxSerializer = new SAXSerializer(writer, OUTPUT_PROPERTIES);
83+
84+
saxSerializer.startDocument();
85+
saxSerializer.startElement(new QName("meta", "http://exist-db.org/xquery/repo", null), null);
86+
saxSerializer.startElement(new QName("changelog", "http://exist-db.org/xquery/repo", null), null);
87+
88+
saxSerializer.startElement(new QName("change", "http://exist-db.org/xquery/repo", null), null);
89+
saxSerializer.endElement(new QName("change", "http://exist-db.org/xquery/repo", null));
90+
91+
saxSerializer.startElement(new QName("change", "http://exist-db.org/xquery/repo", null), null);
92+
saxSerializer.characters("change-text-1");
93+
saxSerializer.endElement(new QName("change", "http://exist-db.org/xquery/repo", null));
94+
95+
saxSerializer.startElement(new QName("change", "http://exist-db.org/xquery/repo", "repo"), null);
96+
saxSerializer.endElement(new QName("change", "http://exist-db.org/xquery/repo", "repo"));
97+
98+
saxSerializer.startElement(new QName("change", "http://exist-db.org/xquery/repo", "repo"), null);
99+
saxSerializer.characters("change-text-2");
100+
saxSerializer.endElement(new QName("change", "http://exist-db.org/xquery/repo", "repo"));
101+
102+
saxSerializer.endElement(new QName("changelog", "http://exist-db.org/xquery/repo", null));
103+
saxSerializer.endElement(new QName("meta", "http://exist-db.org/xquery/repo", null));
104+
saxSerializer.endDocument();
105+
106+
assertEquals("<meta xmlns=\"http://exist-db.org/xquery/repo\"><changelog><change/><change>change-text-1</change><change/><change>change-text-2</change></changelog></meta>", writer.toString());
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)