String (String prefix) { BidirectionalMap<String, String> map = getNamespaceMap(myTag); if (map != null) { final String ns = map.get(prefix); if (ns != null) return ns; } XmlTag parentTag = myTag.getParentTag(); if (parentTag != null) return parentTag.getNamespaceByPrefix(prefix); //The prefix 'xml' is by definition bound to the namespace name http://www.w3.org/XML/1998/namespace. It MAY, but need not, be declared if (XML_NS_PREFIX.equals(prefix)) return XmlUtil.XML_NAMESPACE_URI; if (!prefix.isEmpty() && !myTag.hasNamespaceDeclarations() && myTag.getNamespacePrefix().equals(prefix)) { // When there is no namespace declarations then qualified names should be just used in dtds // myTag implies that we may have "" namespace prefix ! (see last paragraph in Namespaces in Xml, Section 5) String result = RecursionManager.doPreventingRecursion(Trinity.create("getNsByPrefix", myTag, prefix), true, () -> { final String nsFromEmptyPrefix = myTag.getNamespaceByPrefix(""); if (nsFromEmptyPrefix.isEmpty()) return nsFromEmptyPrefix; final XmlNSDescriptor nsDescriptor = myTag.getNSDescriptor(nsFromEmptyPrefix, false); final XmlElementDescriptor descriptor = nsDescriptor != null ? nsDescriptor.getElementDescriptor(myTag) : null; final String nameFromRealDescriptor = descriptor != null && descriptor.getDeclaration() != null && descriptor.getDeclaration().isPhysical() ? descriptor.getName() : ""; if (nameFromRealDescriptor.equals(myTag.getName())) return nsFromEmptyPrefix; return XmlUtil.EMPTY_URI; }); if (result != null) { return result; } } return XmlUtil.EMPTY_URI; }