List<XmlElementDescriptor> (final XmlTag element, final Collection<String> namespaces, @Nullable List<? super String> nsInfo) { XmlElementDescriptor elementDescriptor = null; String elementNamespace = element.getNamespacePrefix().isEmpty() ? null : element.getNamespace(); final Map<String, XmlElementDescriptor> descriptorsMap = new HashMap<>(); XmlTag context = element.getParentTag(); XmlTag declarationTag = context; while(declarationTag != null){ final String namespace = declarationTag.getNamespace(); if(!descriptorsMap.containsKey(namespace)) { final XmlElementDescriptor descriptor = declarationTag.getDescriptor(); if(descriptor != null) { descriptorsMap.put(namespace, descriptor); if(elementDescriptor == null) { elementDescriptor = descriptor; if (elementNamespace == null) { elementNamespace = namespace; } } } } declarationTag = declarationTag.getParentTag(); } final Set<XmlNSDescriptor> visited = new HashSet<>(); final XmlExtension extension = XmlExtension.getExtension(element.getContainingFile()); final ArrayList<XmlElementDescriptor> variants = new ArrayList<>(); for (final String namespace: namespaces) { final int initialSize = variants.size(); processVariantsInNamespace(namespace, element, variants, elementDescriptor, elementNamespace, descriptorsMap, visited, context != null ? context : element, extension); if (nsInfo != null) { for (int i = initialSize; i < variants.size(); i++) { XmlElementDescriptor descriptor = variants.get(i); nsInfo.add(descriptor instanceof XmlElementDescriptorImpl && !(descriptor instanceof RelaxedHtmlFromSchemaElementDescriptor) ? ((XmlElementDescriptorImpl)descriptor).getNamespaceByContext(element) : namespace); } } } final boolean hasPrefix = StringUtil.isNotEmpty(element.getNamespacePrefix()); return ContainerUtil.filter(variants, descriptor -> { if (descriptor instanceof AnyXmlElementDescriptor) { return false; } else if (hasPrefix && descriptor instanceof XmlElementDescriptorImpl && !namespaces.contains(((XmlElementDescriptorImpl)descriptor).getNamespace())) { return false; } return true; }); }