Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Project: Stax2 API
(contributed by @winfriedgerlach)
#45: Fix swapped arguments in `AttributeEventImpl.writeUsing()`
(contributed by @winfriedgerlach)
#47: `MergedNsContext.getPrefixes()` returns null instead of result
(contributed by @winfriedgerlach)
- Branch "master" renamed as "main"

4.3.0 (31-Mar-2026)
Expand Down
24 changes: 17 additions & 7 deletions src/main/java/org/codehaus/stax2/ri/evt/MergedNsContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.events.Namespace;

import org.codehaus.stax2.ri.EmptyIterator;

/**
* Helper class used to combine an enclosing namespace context with
* a list of namespace declarations contained, to result in a single
Expand Down Expand Up @@ -129,8 +131,7 @@ public Iterator<String> getPrefixes(String nsURI)

// Any local bindings?
ArrayList<String> l = null;
for (int i = 0, len = _namespaces.size(); i < len; ++i) {
Namespace ns = _namespaces.get(i);
for (Namespace ns : _namespaces) {
if (nsURI.equals(ns.getNamespaceURI())) {
l = addToList(l, ns.getPrefix());
}
Expand All @@ -144,21 +145,22 @@ public Iterator<String> getPrefixes(String nsURI)
// But is it masked?
String uri2 = getNamespaceURI(p2);
if (uri2.equals(nsURI)) {
// No masking, we are good:
l = addToList(l, p2);
// No masking, we are good (but may already have it, if re-bound locally)
l = addIfMissing(l, p2);
}
}
}

// Ok, but how about pre-defined ones (for xml, xmlns)?
// (parent context may have already reported these)
if (nsURI.equals(XMLConstants.XML_NS_URI)) {
l = addToList(l, XMLConstants.XML_NS_PREFIX);
l = addIfMissing(l, XMLConstants.XML_NS_PREFIX);
}
if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
l = addToList(l, XMLConstants.XMLNS_ATTRIBUTE);
l = addIfMissing(l, XMLConstants.XMLNS_ATTRIBUTE);
}

return null;
return l == null ? EmptyIterator.getInstance() : l.iterator();
}

/*
Expand All @@ -175,4 +177,12 @@ protected <T> ArrayList<T> addToList(ArrayList<T> l, T value)
l.add(value);
return l;
}

private <T> ArrayList<T> addIfMissing(ArrayList<T> l, T value)
{
if (l != null && l.contains(value)) {
return l;
}
return addToList(l, value);
}
}
59 changes: 59 additions & 0 deletions src/test/java/org/codehaus/stax2/ri/evt/MergedNsContextTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.codehaus.stax2.ri.evt;

import java.util.*;

import javax.xml.XMLConstants;
import javax.xml.stream.events.Namespace;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
* Tests for {@link MergedNsContext}, mostly regarding
* [stax2-api#47]: {@code getPrefixes()} returned null.
*/
public class MergedNsContextTest
{
@Test
public void testGetPrefixes()
{
List<Namespace> ns = new ArrayList<>();
ns.add(NamespaceEventImpl.constructNamespace(null, "a", "urn:test"));
ns.add(NamespaceEventImpl.constructNamespace(null, "b", "urn:test"));
ns.add(NamespaceEventImpl.constructNamespace(null, "c", "urn:other"));
MergedNsContext ctxt = MergedNsContext.construct(null, ns);

assertEquals(Arrays.asList("a", "b"), toList(ctxt.getPrefixes("urn:test")));
assertEquals(Arrays.asList("c"), toList(ctxt.getPrefixes("urn:other")));
// No match: must get empty iterator, not null
Iterator<String> it = ctxt.getPrefixes("urn:missing");
assertNotNull(it);
assertFalse(it.hasNext());
}

@Test
public void testGetPrefixesNoDuplicates()
{
MergedNsContext parent = MergedNsContext.construct(null,
Arrays.<Namespace>asList(NamespaceEventImpl.constructNamespace(null, "p", "urn:test")));
// Same binding re-declared locally
MergedNsContext ctxt = MergedNsContext.construct(parent,
Arrays.<Namespace>asList(NamespaceEventImpl.constructNamespace(null, "p", "urn:test")));

assertEquals(Arrays.asList("p"), toList(ctxt.getPrefixes("urn:test")));
// Parent also reports pre-defined "xml" prefix
assertEquals(Arrays.asList("xml"),
toList(ctxt.getPrefixes(XMLConstants.XML_NS_URI)));
}

private static List<String> toList(Iterator<String> it)
{
assertNotNull(it);
List<String> result = new ArrayList<>();
while (it.hasNext()) {
result.add(it.next());
}
return result;
}
}
Loading