QNameComparator implements Comparator<QName> { @Override public int compare(final QName o1, final QName o2) { final boolean isXmlNs1 = o1.getPrefix().equalsIgnoreCase(XMLConstants.XML_NS_PREFIX); final boolean isXmlNs2 = o2.getPrefix().equalsIgnoreCase(XMLConstants.XML_NS_PREFIX); if (isXmlNs1 && !isXmlNs2) { return LESS_THAN; } else if (!isXmlNs1 && isXmlNs2) { return GREATER_THAN; } if (!o1.getPrefix().equalsIgnoreCase(XMLConstants.DEFAULT_NS_PREFIX) && o2.getPrefix().equalsIgnoreCase(XMLConstants.DEFAULT_NS_PREFIX)) { return LESS_THAN; } else if (o1.getPrefix().equalsIgnoreCase(XMLConstants.DEFAULT_NS_PREFIX) && !o2.getPrefix().equalsIgnoreCase(XMLConstants.DEFAULT_NS_PREFIX)) { return GREATER_THAN; } else { String lowerCaseQName1 = o1.getPrefix().toLowerCase(Locale.ROOT) + o1.getLocalPart().toLowerCase(Locale.ROOT); String lowerCaseQName2 = o2.getPrefix().toLowerCase(Locale.ROOT) + o2.getLocalPart().toLowerCase(Locale.ROOT); final int c = lowerCaseQName1.compareTo(lowerCaseQName2); if (c == EQUAL) { String qName1 = o1.getPrefix() + o1.getLocalPart(); String qName2 = o2.getPrefix() + o2.getLocalPart(); return qName1.compareTo(qName2); } return c; } }  @Override int compare(final QName o1, final QName o2); static final QNameComparator INSTANCE; }
@Test public void testCompare() { List<QName> names = new LinkedList<>(); QName name1 = new QName("localonly"); names.add(name1); QName name2 = new QName(XMLConstants.XML_NS_URI, "xhtml", XMLConstants.XML_NS_PREFIX); names.add(name2); QName name3 = new QName(NamespaceRegistry.NAMESPACE_JCR, "UpperCase", NamespaceRegistry.PREFIX_JCR); names.add(name3); QName name4 = new QName(NamespaceRegistry.NAMESPACE_JCR, "primaryType", NamespaceRegistry.PREFIX_JCR); names.add(name4); QName name5 = new QName(NamespaceRegistry.NAMESPACE_JCR, "PrimaryType", NamespaceRegistry.PREFIX_JCR); names.add(name5); Collections.sort(names, new QNameComparator()); Assert.assertThat(names, Matchers.contains(name2, name5, name4, name3, name1)); }