diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java index 379436d1b08..46bbe39b1af 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/AbstractStaxXMLReader.java @@ -16,6 +16,8 @@ package org.springframework.util.xml; +import java.util.LinkedHashMap; +import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamException; @@ -54,6 +56,7 @@ abstract class AbstractStaxXMLReader extends AbstractXMLReader { private Boolean isStandalone; + private final Map namespaces = new LinkedHashMap(); @Override public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { @@ -169,6 +172,37 @@ abstract class AbstractStaxXMLReader extends AbstractXMLReader { */ protected abstract void parseInternal() throws SAXException, XMLStreamException; + /** + * Starts the prefix mapping for the given prefix. + * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String) + */ + protected void startPrefixMapping(String prefix, String namespace) throws SAXException { + if (getContentHandler() != null) { + if (prefix == null) { + prefix = ""; + } + if (!StringUtils.hasLength(namespace)) { + return; + } + if (!namespace.equals(namespaces.get(prefix))) { + getContentHandler().startPrefixMapping(prefix, namespace); + namespaces.put(prefix, namespace); + } + } + } + + /** + * Ends the prefix mapping for the given prefix. + * @see org.xml.sax.ContentHandler#endPrefixMapping(String) + */ + protected void endPrefixMapping(String prefix) throws SAXException { + if (getContentHandler() != null) { + if (namespaces.containsKey(prefix)) { + getContentHandler().endPrefixMapping(prefix); + namespaces.remove(prefix); + } + } + } /** * Implementation of the Locator interface that is based on a StAX Location. diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java index af667773cb3..9fdd05ae7a8 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java @@ -17,6 +17,8 @@ package org.springframework.util.xml; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLEventReader; @@ -61,6 +63,8 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { private final XMLEventReader reader; + private final Map namespaces = new LinkedHashMap(); + private String xmlVersion = DEFAULT_XML_VERSION; private String encoding; @@ -199,19 +203,12 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { if (hasNamespacesFeature()) { for (Iterator i = startElement.getNamespaces(); i.hasNext();) { Namespace namespace = (Namespace) i.next(); - getContentHandler().startPrefixMapping(namespace.getPrefix(), namespace.getNamespaceURI()); + startPrefixMapping(namespace.getPrefix(), namespace.getNamespaceURI()); } for (Iterator i = startElement.getAttributes(); i.hasNext();){ Attribute attribute = (Attribute) i.next(); - String prefix = attribute.getName().getPrefix(); - if (prefix == null) { - prefix = ""; - } - String namespace = attribute.getName().getNamespaceURI(); - if (namespace == null) { - continue; - } - getContentHandler().startPrefixMapping(prefix, namespace); + QName attributeName = attribute.getName(); + startPrefixMapping(attributeName.getPrefix(), attributeName.getNamespaceURI()); } getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName), @@ -247,7 +244,7 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { getContentHandler().endElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName)); for (Iterator i = endElement.getNamespaces(); i.hasNext();) { Namespace namespace = (Namespace) i.next(); - getContentHandler().endPrefixMapping(namespace.getPrefix()); + endPrefixMapping(namespace.getPrefix()); } } else { diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java index 1168dd1f044..035fa54fa4d 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java +++ b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java @@ -178,22 +178,14 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { QName qName = reader.getName(); if (hasNamespacesFeature()) { for (int i = 0; i < reader.getNamespaceCount(); i++) { - String prefix = reader.getNamespacePrefix(i); - if (prefix == null) { - prefix = ""; - } - getContentHandler().startPrefixMapping(prefix, reader.getNamespaceURI(i)); + startPrefixMapping(reader.getNamespacePrefix(i), reader.getNamespaceURI(i)); } for (int i = 0; i < reader.getAttributeCount(); i++) { String prefix = reader.getAttributePrefix(i); - if (prefix == null) { - prefix = ""; - } String namespace = reader.getAttributeNamespace(i); - if (namespace == null) { - continue; + if (StringUtils.hasLength(namespace)) { + startPrefixMapping(prefix, namespace); } - getContentHandler().startPrefixMapping(prefix, namespace); } getContentHandler().startElement(qName.getNamespaceURI(), qName.getLocalPart(), toQualifiedName(qName), getAttributes()); @@ -214,7 +206,7 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { if (prefix == null) { prefix = ""; } - getContentHandler().endPrefixMapping(prefix); + endPrefixMapping(prefix); } } else {