Skip to content

Commit 90c75f6

Browse files
authored
Merge pull request #62 from evolvedbinary/7.x.x/hotfix/xml-prefix-serialization
[7.x.x] Fixes to namespace prefix coalescence
2 parents 3bf9db6 + cc5f69b commit 90c75f6

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
@@ -751,6 +751,7 @@
751751
<include>src/main/java/org/exist/util/JREUtil.java</include>
752752
<include>src/main/java/org/exist/util/OSUtil.java</include>
753753
<include>src/main/java/org/exist/util/StringUtil.java</include>
754+
<include>src/test/java/org/exist/util/serializer/SAXSerializerTest.java</include>
754755
<include>src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml</include>
755756
<include>src/test/java/org/exist/xquery/ImportFromPkgTest.java</include>
756757
<include>src/main/java/org/exist/xquery/JavaBinding.java</include>
@@ -1390,6 +1391,7 @@
13901391
<exclude>src/main/java/org/exist/util/serializer/EXISerializer.java</exclude>
13911392
<exclude>src/test/java/org/exist/util/serializer/HTML5WriterTest.java</exclude>
13921393
<exclude>src/main/java/org/exist/util/serializer/SAXSerializer.java</exclude>
1394+
<exclude>src/test/java/org/exist/util/serializer/SAXSerializerTest.java</exclude>
13931395
<exclude>src/main/java/org/exist/util/serializer/SerializerObjectFactory.java</exclude>
13941396
<exclude>src/main/java/org/exist/util/serializer/json/JSONObject.java</exclude>
13951397
<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
@@ -327,7 +327,7 @@ public void startElement(final QName qname, final AttrList attribs) throws SAXEx
327327
for (final Map.Entry<String, String> nsEntry : optionalNamespaceDecls.entrySet()) {
328328
final String prefix = nsEntry.getKey();
329329
final String uri = nsEntry.getValue();
330-
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && elemPrefix.equals(prefix))) {
330+
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && StringUtil.equals(qname.getPrefix(), prefix))) {
331331
receiver.namespace(prefix, uri);
332332
}
333333
}
@@ -338,7 +338,7 @@ public void startElement(final QName qname, final AttrList attribs) throws SAXEx
338338
}
339339
final String uri = nsEntry.getValue();
340340
if(!optionalNamespaceDecls.containsKey(prefix)) {
341-
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && elemPrefix.equals(prefix))) {
341+
if (!(elemPrefixedNsIsDefaultNs && uri.equals(namespaceURI) && StringUtil.equals(qname.getPrefix(), prefix))) {
342342
receiver.namespace(prefix, uri);
343343
}
344344
}
@@ -410,7 +410,7 @@ public void endElement(final QName qname) throws SAXException {
410410
if (enforceXHTML && elemPrefix.isEmpty() && namespaceURI.isEmpty()) {
411411
namespaceURI = Namespaces.XHTML_NS;
412412
}
413-
receiver.endElement(new QName(qname.getLocalPart(), namespaceURI, qname.getPrefix()));
413+
receiver.endElement(new QName(qname.getLocalPart(), namespaceURI, elemPrefix));
414414

415415
receiver.setDefaultNamespace(nsSupport.getURI(XMLConstants.DEFAULT_NS_PREFIX));
416416
} 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)