diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
index 22de04f053b9..cfd68e9eeac2 100644
--- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
@@ -109,6 +109,9 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
configureByFile(filePath, null);
}
+ /**
+ * @param files the first file will be loaded in editor
+ */
protected VirtualFile configureByFiles(@Nullable String projectRoot,String... files) throws Exception {
if (files.length == 0) return null;
final VirtualFile[] vFiles = new VirtualFile[files.length];
diff --git a/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java b/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java
index 476e91b40970..51e0ff29c816 100644
--- a/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java
+++ b/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java
@@ -1992,6 +1992,11 @@ public class XmlHighlightingTest extends DaemonAnalyzerTestCase {
doTest(getFullRelativeTestName(".html"), true, true);
}
+ public void testAnyAttribute() throws Exception {
+ configureByFiles(null, BASE_PATH + "anyAttribute.xml", BASE_PATH + "services-1.0.xsd");
+ doDoTest(true, false);
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
diff --git a/xml/tests/testData/xml/anyAttribute.xml b/xml/tests/testData/xml/anyAttribute.xml
new file mode 100644
index 000000000000..56835ab524bb
--- /dev/null
+++ b/xml/tests/testData/xml/anyAttribute.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/tests/testData/xml/services-1.0.xsd b/xml/tests/testData/xml/services-1.0.xsd
new file mode 100644
index 000000000000..f1c2003c6225
--- /dev/null
+++ b/xml/tests/testData/xml/services-1.0.xsd
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java
index a6a2b1a540ed..c2005fa4ba41 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java
@@ -382,7 +382,7 @@ public class ComplexTypeDescriptor extends TypeDescriptor {
}
enum CanContainAttributeType {
- CanContainButSkip, CanContainButDoNotSkip, CanNotContain
+ CanContainButSkip, CanContainButDoNotSkip, CanContainAny, CanNotContain
}
private CanContainAttributeType _canContainAttribute(String namespace,
@@ -401,6 +401,9 @@ public class ComplexTypeDescriptor extends TypeDescriptor {
if (OTHER_NAMESPACE_ATTR_VALUE.equals(ns)) {
return !namespace.equals(myDocumentDescriptor.getDefaultNamespace()) ? canContainAttributeType : CanContainAttributeType.CanNotContain;
}
+ else if ("##any".equals(ns)) {
+ return CanContainAttributeType.CanContainAny;
+ }
return canContainAttributeType;
}
else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attributeGroup")) {
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java
index ac00589000d2..91b8f60009a4 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java
@@ -306,19 +306,21 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab
XmlAttributeDescriptor attribute = getAttribute(localName, namespace, context, attributeName);
- if (attribute instanceof AnyXmlAttributeDescriptor && namespace.length() > 0) {
- final XmlNSDescriptor candidateNSDescriptor = context.getNSDescriptor(namespace, true);
+ if (attribute instanceof AnyXmlAttributeDescriptor) {
+ final ComplexTypeDescriptor.CanContainAttributeType containAttributeType =
+ ((AnyXmlAttributeDescriptor)attribute).getCanContainAttributeType();
+ if (containAttributeType != ComplexTypeDescriptor.CanContainAttributeType.CanContainAny && !namespace.isEmpty()) {
+ final XmlNSDescriptor candidateNSDescriptor = context.getNSDescriptor(namespace, true);
- if (candidateNSDescriptor instanceof XmlNSDescriptorImpl) {
- final XmlNSDescriptorImpl nsDescriptor = (XmlNSDescriptorImpl)candidateNSDescriptor;
+ if (candidateNSDescriptor instanceof XmlNSDescriptorImpl) {
+ final XmlNSDescriptorImpl nsDescriptor = (XmlNSDescriptorImpl)candidateNSDescriptor;
- final XmlAttributeDescriptor xmlAttributeDescriptor = nsDescriptor.getAttribute(localName, namespace, context);
- if (xmlAttributeDescriptor != null) return xmlAttributeDescriptor;
- else {
- final ComplexTypeDescriptor.CanContainAttributeType containAttributeType =
- ((AnyXmlAttributeDescriptor)attribute).getCanContainAttributeType();
- if (containAttributeType == ComplexTypeDescriptor.CanContainAttributeType.CanContainButDoNotSkip) {
- attribute = null;
+ final XmlAttributeDescriptor xmlAttributeDescriptor = nsDescriptor.getAttribute(localName, namespace, context);
+ if (xmlAttributeDescriptor != null) return xmlAttributeDescriptor;
+ else {
+ if (containAttributeType == ComplexTypeDescriptor.CanContainAttributeType.CanContainButDoNotSkip) {
+ attribute = null;
+ }
}
}
}