diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java
index 0da0608ed3..4a5789dd04 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMDocumentType.java
@@ -23,24 +23,20 @@ public enum DocumentTypeKind {
}
// Offset values relative to start of the XML Document
- int nameStart = -1;
- int nameEnd = -1;
- int kindStart = -1;
- int kindEnd = -1;
- int publicIdStart = -1;
- int publicIdEnd = -1;
- int systemIdStart = -1;
- int systemIdEnd = -1;
- Integer startInternalSubset;
- Integer endInternalSubset;
+ Integer nameStart, nameEnd;
+ Integer kindStart, kindEnd;
+ Integer publicIdStart, publicIdEnd;
+ Integer systemIdStart, systemIdEnd;
+ Integer internalSubsetStart, internalSubsetEnd;
+
private String name;
- private String kind;
+ private String kind; // SYSTEM || PUBLIC
private String publicId;
private String systemId;
private String internalSubset;
- private String content;
+ private String content; // ||
public DOMDocumentType(int start, int end, DOMDocument ownerDocument) {
super(start, end, ownerDocument);
@@ -63,7 +59,7 @@ void setEnd(int end) {
*/
@Override
public String getName() {
- if (name == null && this.nameStart != -1 && this.nameEnd != -1) {
+ if (name == null && this.nameStart != null && this.nameEnd != null) {
name = getSubstring(nameStart, nameEnd);
}
return name;
@@ -78,7 +74,7 @@ void setName(int start, int end) {
* @return the DocumentTypeKind
*/
public String getKind() {
- if (kind == null && kindStart != -1 && kindEnd != -1) {
+ if (kind == null && kindStart != null && kindEnd != null) {
kind = getSubstring(kindStart, kindEnd);
}
return kind;
@@ -129,8 +125,8 @@ public NamedNodeMap getEntities() {
*/
@Override
public String getInternalSubset() {
- if (internalSubset == null && startInternalSubset != null && endInternalSubset != null) {
- internalSubset = getSubstring(startInternalSubset + 1, endInternalSubset);
+ if (internalSubset == null && internalSubsetStart != null && internalSubsetEnd != null) {
+ internalSubset = getSubstring(internalSubsetStart + 1, internalSubsetEnd - 1);
}
return internalSubset;
}
@@ -141,7 +137,7 @@ public String getInternalSubset() {
* @return the start offset of internal subset and null otherwise.
*/
public Integer getStartInternalSubset() {
- return startInternalSubset;
+ return internalSubsetStart;
}
/**
@@ -150,7 +146,7 @@ public Integer getStartInternalSubset() {
* @return the end offset of internal subset and null otherwise.
*/
public Integer getEndInternalSubset() {
- return endInternalSubset;
+ return internalSubsetEnd;
}
/*
@@ -170,7 +166,7 @@ public NamedNodeMap getNotations() {
*/
@Override
public String getPublicId() {
- if (publicId == null && publicIdStart != -1 && publicIdEnd != -1) {
+ if (publicId == null && publicIdStart != null && publicIdEnd != null) {
publicId = cleanURL(getSubstring(publicIdStart, publicIdEnd));
}
return publicId;
@@ -191,7 +187,7 @@ void setPublicId(int start, int end) {
*/
@Override
public String getSystemId() {
- if (systemId == null && systemIdStart != -1 && systemIdEnd != -1) {
+ if (systemId == null && systemIdStart != null && systemIdEnd != null) {
systemId = cleanURL(getSubstring(systemIdStart, systemIdEnd));
}
return systemId;
@@ -220,7 +216,11 @@ private static String cleanURL(String url) {
return url.substring(start, end);
}
- private String getSubstring(int start, int end) {
+ /**
+ * Since offset values are relative to 'this.start' we need to
+ * subtract getStart() to make them relative to 'content'
+ */
+ public String getSubstring(int start, int end) {
return getContent().substring(start - getStart(), end - getStart());
}
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMNode.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMNode.java
index 8b77732615..acf6adf986 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMNode.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMNode.java
@@ -37,6 +37,21 @@ public abstract class DOMNode implements Node {
*/
public static final short DTD_ATT_LIST_NODE = 102;
+ /**
+ * The node is a DTD Entity Declaraction
.
+ */
+ public static final short DTD_ENTITY_DECL_NODE = 103;
+
+ /**
+ * The node is a DTD Notation Declaraction
.
+ */
+ public static final short DTD_NOTATION_DECL = 104;
+
+ /**
+ * The node is a generic DTD Decl Node
.
+ */
+ public static final short DTD_DECL_NODE = 105;
+
boolean closed = false;
private XMLNamedNodeMap attributeNodes;
@@ -119,6 +134,7 @@ public DOMNode(int start, int end, DOMDocument ownerDocument) {
this.start = start;
this.end = end;
this.ownerDocument = ownerDocument;
+ this.closed = false;
}
public DOMDocument getOwnerDocument() {
@@ -341,7 +357,7 @@ public List getChildren() {
}
/**
- * Add node child and set child.parent to this.
+ * Add node child and set child.parent to {@code this}
*
* @param child the node child to add.
*/
@@ -399,6 +415,11 @@ public boolean isDoctype() {
return getNodeType() == DOMNode.DOCUMENT_TYPE_NODE;
}
+ public boolean isGenericDTDDecl() {
+ return getNodeType() == DOMNode.DTD_DECL_NODE;
+ }
+
+
public boolean isElement() {
return getNodeType() == DOMNode.ELEMENT_NODE;
}
@@ -427,6 +448,10 @@ public boolean isDTDEntityDecl() {
return getNodeType() == Node.ENTITY_NODE;
}
+ public boolean isDTDNotationDecl() {
+ return getNodeType() == DOMNode.DTD_NOTATION_DECL;
+ }
+
public int getStart() {
return start;
}
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMParser.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMParser.java
index accda2ee88..dd11a36511 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMParser.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DOMParser.java
@@ -52,11 +52,16 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
DOMNode curr = isDTD ? new DOMDocumentType(0, text.length(), xmlDocument) : xmlDocument;
if (isDTD) {
xmlDocument.addChild(curr);
+
+ // This DOMDocumentType object is hidden, and just represents the DTD file
+ // nothing should affect it's closed status
+ curr.closed = true;
}
DOMNode lastClosed = curr;
DOMAttr attr = null;
int endTagOpenOffset = -1;
String pendingAttribute = null;
+ boolean isInitialDeclaration = true; // A declaration can have multiple internal declarations
TokenType token = scanner.scan();
while (token != TokenType.EOS) {
switch (token) {
@@ -64,6 +69,9 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
if(curr.parent != null) {
curr.end = scanner.getTokenOffset();
}
+ if(curr.isDoctype() && curr.parent != null) {
+ curr = curr.parent;
+ }
DOMElement child = xmlDocument.createElement(scanner.getTokenOffset(), scanner.getTokenEnd());
child.startTagOpenOffset = scanner.getTokenOffset();
curr.addChild(child);
@@ -240,6 +248,9 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
case StartCommentTag: {
DOMComment comment = xmlDocument.createComment(scanner.getTokenOffset(), text.length());
+ if(curr.parent != null && curr.parent.isDoctype()) {
+ curr.parent.addChild(comment);
+ }
curr.addChild(comment);
curr = comment;
try {
@@ -275,6 +286,12 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
if (content.trim().length() == 0) { // if string is only whitespaces
break;
}
+ if (curr instanceof DTDDeclNode) {
+ curr.end = scanner.getTokenOffset() - 1;
+ if(!curr.isDoctype()) {
+ curr = curr.getParentNode();
+ }
+ }
int start = scanner.getTokenOffset();
int end = scanner.getTokenEnd();
DOMText textNode = xmlDocument.createText(start, end);
@@ -325,7 +342,7 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
case DTDStartInternalSubset: {
DOMDocumentType doctype = (DOMDocumentType) curr;
- doctype.startInternalSubset = scanner.getTokenOffset();
+ doctype.internalSubsetStart = scanner.getTokenOffset();
break;
}
@@ -336,11 +353,12 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
}
DOMDocumentType doctype = (DOMDocumentType) curr;
- doctype.endInternalSubset = scanner.getTokenOffset();
+ doctype.internalSubsetEnd = scanner.getTokenEnd();
break;
}
- case DTDStartElementDecl: {
+ case DTDStartElement: {
+ //If previous 'curr' was an unclosed ENTITY, ELEMENT, or ATTLIST
if (!curr.isDoctype()) {
curr.end = scanner.getTokenOffset() - 1;
curr = curr.getParentNode();
@@ -355,56 +373,207 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
case DTDElementDeclName: {
DTDElementDecl element = (DTDElementDecl) curr;
- element.name = scanner.getTokenText();
+ element.nameStart = scanner.getTokenOffset();
+ element.nameEnd = scanner.getTokenEnd();
break;
}
- case DTDStartAttlistDecl: {
- if (!curr.isDoctype()) {
+ case DTDElementCategory: {
+ DTDElementDecl element = (DTDElementDecl) curr;
+ element.categoryStart = scanner.getTokenOffset();
+ element.categoryEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDStartElementContent: {
+ DTDElementDecl element = (DTDElementDecl) curr;
+ element.contentStart = scanner.getTokenOffset();
+ break;
+ }
+
+ case DTDElementContent: {
+ DTDElementDecl element = (DTDElementDecl) curr;
+ element.contentEnd = scanner.getTokenEnd();
+ }
+
+ case DTDEndElementContent: {
+ DTDElementDecl element = (DTDElementDecl) curr;
+ element.contentEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDStartAttlist: {
+ if (!curr.isDoctype()) { // If previous DTD Decl was unclosed
curr.end = scanner.getTokenOffset() - 1;
- curr =curr.getParentNode();
+ curr = curr.getParentNode();
}
DTDAttlistDecl child = new DTDAttlistDecl(scanner.getTokenOffset(), text.length(),
(DOMDocumentType) curr);
+
+ isInitialDeclaration = true;
curr.addChild(child);
curr = child;
+
break;
}
case DTDAttlistElementName: {
DTDAttlistDecl attribute = (DTDAttlistDecl) curr;
- attribute.elementName = scanner.getTokenText();
+ attribute.elementNameStart = scanner.getTokenOffset();
+ attribute.elementNameEnd = scanner.getTokenEnd();
break;
}
+
case DTDAttlistAttributeName: {
DTDAttlistDecl attribute = (DTDAttlistDecl) curr;
- attribute.name = scanner.getTokenText();
+ if(isInitialDeclaration == false) {
+ // All additional declarations are created as new DTDAttlistDecl's
+ DTDAttlistDecl child = new DTDAttlistDecl(-1, -1, null); // Wont use these values
+ attribute.addAdditionalAttDecl(child);
+ child.parent = attribute;
+
+ attribute = child;
+ curr = child;
+ }
+
+ attribute.attributeNameStart = scanner.getTokenOffset();
+ attribute.attributeNameEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDAttlistAttributeType: {
+ DTDAttlistDecl attribute = (DTDAttlistDecl) curr;
+ attribute.attributeTypeStart = scanner.getTokenOffset();
+ attribute.attributeTypeEnd = scanner.getTokenEnd();
break;
}
+
+ case DTDAttlistAttributeValue: {
+ DTDAttlistDecl attribute = (DTDAttlistDecl) curr;
+ attribute.attributeValueStart = scanner.getTokenOffset();
+ attribute.attributeValueEnd = scanner.getTokenEnd();
+
+ if(attribute.parent.isDTDAttListDecl()) { // Is not the root/main ATTLIST node
+ curr = attribute.parent;
+ }
+ else {
+ isInitialDeclaration = false;
+ }
+ break;
+ }
+
case DTDStartEntity: {
+ if (!curr.isDoctype()) { // If previous DTD Decl was unclosed
+ curr.end = scanner.getTokenOffset() - 1;
+ curr = curr.getParentNode();
+ }
DTDEntityDecl child = new DTDEntityDecl(scanner.getTokenOffset(), text.length(), (DOMDocumentType) curr);
curr.addChild(child);
curr = child;
break;
}
+ case DTDEntityPercent: {
+ DTDEntityDecl entity = (DTDEntityDecl) curr;
+ entity.percentStart = scanner.getTokenOffset();
+ entity.percentEnd = scanner.getTokenEnd();
+ break;
+ }
+
case DTDEntityName : {
DTDEntityDecl entity = (DTDEntityDecl) curr;
- entity.name = scanner.getTokenText();
+ entity.nameStart = scanner.getTokenOffset();
+ entity.nameEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDEntityValue : {
+ DTDEntityDecl entity = (DTDEntityDecl) curr;
+ entity.valueStart = scanner.getTokenOffset();
+ entity.valueEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDEntityKindPUBLIC:
+ case DTDEntityKindSYSTEM: {
+ DTDEntityDecl entity = (DTDEntityDecl) curr;
+ entity.kindStart = scanner.getTokenOffset();
+ entity.kindEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDEntityPublicId: {
+ DTDEntityDecl entity = (DTDEntityDecl) curr;
+ entity.publicIdStart = scanner.getTokenOffset();
+ entity.publicIdEnd = scanner.getTokenEnd();
+ break;
+ }
+
+ case DTDEntitySystemId: {
+ DTDEntityDecl entity = (DTDEntityDecl) curr;
+ entity.systemIdStart = scanner.getTokenOffset();
+ entity.systemIdEnd = scanner.getTokenEnd();
break;
}
+
+
+ case DTDStartNotation: {
+ if (!curr.isDoctype()) { // If previous DTD Decl was unclosed
+ curr.end = scanner.getTokenOffset() - 1;
+ curr = curr.getParentNode();
+ }
+ DTDNotationDecl child = new DTDNotationDecl(scanner.getTokenOffset(), text.length(), (DOMDocumentType) curr);
+ curr.addChild(child);
+ curr = child;
+ isInitialDeclaration = true;
+ break;
+ }
+
+ case DTDNotationName: {
+ DTDNotationDecl notation = (DTDNotationDecl) curr;
+ notation.setName(scanner.getTokenOffset(), scanner.getTokenEnd());
+ break;
+ }
+
+ case DTDNotationKindPUBLIC: {
+ DTDNotationDecl notation = (DTDNotationDecl) curr;
+ notation.setKind(scanner.getTokenOffset(), scanner.getTokenEnd());
+ break;
+ }
+
+ case DTDNotationKindSYSTEM: {
+ DTDNotationDecl notation = (DTDNotationDecl) curr;
+ notation.setKind(scanner.getTokenOffset(), scanner.getTokenEnd());
+ break;
+ }
+
+ case DTDNotationPublicId: {
+ DTDNotationDecl notation = (DTDNotationDecl) curr;
+ notation.setPublicId(scanner.getTokenOffset(), scanner.getTokenEnd());
+ break;
+ }
+
+ case DTDNotationSystemId: {
+ DTDNotationDecl notation = (DTDNotationDecl) curr;
+ notation.setSystemId(scanner.getTokenOffset(), scanner.getTokenEnd());
+ break;
+ }
+
case DTDEndTag: {
- if ((curr.isDTDElementDecl() || curr.isDTDAttListDecl() || curr.isDTDEntityDecl()) && curr.parent != null) {
+ if ((curr.isDTDElementDecl() || curr.isDTDAttListDecl() || curr.isDTDEntityDecl() || curr.isDTDNotationDecl()) && curr.parent != null) {
+ if(curr.isDTDNotationDecl() && curr.parent.isDoctype() == false) {
+ curr = curr.parent;
+ }
curr.end = scanner.getTokenEnd();
curr.closed = true;
curr = curr.parent;
}
break;
}
-
+
case DTDEndDoctypeTag: {
((DOMDocumentType) curr).setEnd(scanner.getTokenEnd());
curr.closed = true;
@@ -412,6 +581,13 @@ public DOMDocument parse(TextDocument document, URIResolverExtensionManager reso
break;
}
+ case DTDUnrecognizedParameters: {
+ DTDDeclNode node = (DTDDeclNode) curr;
+ node.unrecognizedStart = scanner.getTokenOffset();
+ node.unrecognizedEnd = scanner.getTokenEnd();
+ break;
+ }
+
default:
}
token = scanner.scan();
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDAttlistDecl.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDAttlistDecl.java
index 6439ebaf7b..519b80fb6b 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDAttlistDecl.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDAttlistDecl.java
@@ -10,54 +10,117 @@
*/
package org.eclipse.lsp4xml.dom;
+import java.util.ArrayList;
+
/**
* DTD Attribute List declaration ""
+ *
+ * or
+ *
+ *
+ */
- private final DOMDocumentType ownerDTDDocument;
+ Integer elementNameStart, elementNameEnd;
+ Integer attributeNameStart, attributeNameEnd;
+ Integer attributeTypeStart, attributeTypeEnd;
+ Integer attributeValueStart, attributeValueEnd;
- String name;
String elementName;
+ String attributeName;
+ String attributeType;
+ String attributeValue;
+
+ ArrayList internalChildren;
- public DTDAttlistDecl(int start, int end, DOMDocumentType ownerDTDDocument) {
- super(start, end, ownerDTDDocument.getOwnerDocument());
- this.ownerDTDDocument = ownerDTDDocument;
+ public DTDAttlistDecl(int start, int end, DOMDocumentType parentDocumentType) {
+ super(start, end, parentDocumentType);
}
- public DOMDocumentType getOwnerDocumentType() {
- return ownerDTDDocument;
+ public DOMDocumentType getParentDocumentType() {
+ return parentDocumentType;
}
@Override
public String getNodeName() {
- return getName();
+ return getAttributeName();
}
- /**
- * Returns the attribute name
- *
- * @return the attribute name
- */
- public String getName() {
- return name;
- }
-
/**
* Returns the element name
*
* @return the element name
*/
public String getElementName() {
+ elementName = getValueFromOffsets(parentDocumentType, elementName, elementNameStart, elementNameEnd);
return elementName;
}
+ /**
+ * Returns the attribute name
+ *
+ * @return the attribute name
+ */
+ public String getAttributeName() {
+ attributeName = getValueFromOffsets(parentDocumentType, attributeName, attributeNameStart, attributeNameEnd);
+ return attributeName;
+ }
+
+ public String getAttributeType() {
+ attributeType = getValueFromOffsets(parentDocumentType, attributeType, attributeTypeStart, attributeTypeEnd);
+ return attributeType;
+ }
+
+ public String getAttributeValue() {
+ attributeValue = getValueFromOffsets(parentDocumentType, attributeValue, attributeValueStart, attributeValueEnd);
+ return attributeValue;
+ }
+
@Override
public short getNodeType() {
return DOMNode.DTD_ATT_LIST_NODE;
}
+ /**
+ * Add another internal attlist declaration to the list of children.
+ *
+ * An ATTLIST decl can internally declare multiple declarations, see top of file.
+ * This will add another one to its list of additional declarations.
+ */
+ void addAdditionalAttDecl(DTDAttlistDecl child) {
+ if(internalChildren == null) {
+ internalChildren = new ArrayList();
+ }
+ internalChildren.add(child);
+ }
+
+ public ArrayList getInternalChildren() {
+ return internalChildren;
+ }
+
+ /**
+ * Returns true if this node's parent is the Doctype node.
+ *
+ *
+ * This is used because an Attlist declaration can have multiple
+ * attribute declarations within a tag that are each represented
+ * by this class.
+ */
+ public boolean isRootAttlist() {
+ return this.parent.isDoctype();
+ }
+
}
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java
new file mode 100644
index 0000000000..12c3103baf
--- /dev/null
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDDeclNode.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.lsp4xml.dom;
+
+/**
+ * DTDNode
+ */
+public class DTDDeclNode extends DOMNode{
+
+ /**
+ * This class is the base for all declaration nodes for DTD's.
+ *
+ * It can also be used to represent an undefined tag, meaning
+ * it is not any of: ELEMENT, ATTLIST, ENTITY, or NOTATION
+ */
+
+ protected final DOMDocumentType parentDocumentType;
+
+ Integer unrecognizedStart, unrecognizedEnd;
+
+ String unrecognized; // holds all content after parsing goes wrong in a DTD declaration (ENTITY, ATTLIST, ELEMENT).
+
+ public DTDDeclNode(int start, int end, DOMDocumentType parentDocumentType) {
+ super(start, end, parentDocumentType != null ? parentDocumentType.getOwnerDocument() : null);
+ this.parentDocumentType = parentDocumentType;
+ }
+
+ @Override
+ public String getNodeName() {
+ return null;
+ }
+
+ @Override
+ public short getNodeType() {
+ return DOMNode.DTD_DECL_NODE;
+ }
+
+ public String getUnrecognized() {
+ unrecognized = getValueFromOffsets(parentDocumentType, unrecognized, unrecognizedStart, unrecognizedEnd);
+ return unrecognized;
+ }
+
+ public static String getValueFromOffsets(DOMDocumentType document, String value, Integer start, Integer end) {
+ if(value == null && start != null && end != null) {
+ return document.getSubstring(start, end);
+ }
+ return value;
+ }
+
+
+}
\ No newline at end of file
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java
index a97bfa3abb..7d9673288b 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDElementDecl.java
@@ -16,18 +16,32 @@
* @see https://www.w3.org/TR/REC-xml/#dt-eldecl
*
*/
-public class DTDElementDecl extends DOMNode {
+public class DTDElementDecl extends DTDDeclNode {
+
+ /**
+ Formats:
+
+
+ or
+
+
+ */
+
+ Integer nameStart, nameEnd; //
+ Integer categoryStart, categoryEnd; //
+ Integer contentStart,contentEnd; //
- private final DOMDocumentType ownerDTDDocument;
String name;
+ String category;
+ String content;
+
- public DTDElementDecl(int start, int end, DOMDocumentType ownerDTDDocument) {
- super(start, end, ownerDTDDocument.getOwnerDocument());
- this.ownerDTDDocument = ownerDTDDocument;
+ public DTDElementDecl(int start, int end, DOMDocumentType parentDocumentType) {
+ super(start, end, parentDocumentType);
}
- public DOMDocumentType getOwnerDocumentType() {
- return ownerDTDDocument;
+ public DOMDocumentType getParentDocumentType() {
+ return parentDocumentType;
}
@Override
@@ -36,9 +50,20 @@ public String getNodeName() {
}
public String getName() {
+ name = getValueFromOffsets(parentDocumentType, name, nameStart, nameEnd);
return name;
}
+ public String getCategory() {
+ category = getValueFromOffsets(parentDocumentType, category, categoryStart, categoryEnd);
+ return category;
+ }
+
+ public String getContent() {
+ content = getValueFromOffsets(parentDocumentType, content, contentStart, contentEnd);
+ return content;
+ }
+
@Override
public short getNodeType() {
return DOMNode.DTD_ELEMENT_DECL_NODE;
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDEntityDecl.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDEntityDecl.java
index 4c39c2c293..809ce6a2ed 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDEntityDecl.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDEntityDecl.java
@@ -18,12 +18,58 @@
*
* @see https://www.w3.org/TR/REC-xml/#dt-entdecl
*/
-public class DTDEntityDecl extends DOMNode implements Entity {
+public class DTDEntityDecl extends DTDDeclNode implements Entity {
+
+
+ /**
+ * Formats:
+ *
+ *
+ *
+ * or
+ *
+ *
+ *
+ * or
+ *
+ *
+ *
+ * or
+ *
+ *
+ *
+ * or
+ *
+ *
+ *
+ * or
+ *
+ *
+ */
String name;
+ String value;
+ String kind;
+ String publicId;
+ String systemId;
+
+ Integer percentStart, percentEnd;
+ Integer nameStart, nameEnd;
+ Integer valueStart, valueEnd;
+ Integer kindStart, kindEnd;
+ Integer publicIdStart, publicIdEnd;
+ Integer systemIdStart, systemIdEnd;
+
- public DTDEntityDecl(int start, int end, DOMDocumentType documentType) {
- super(start, end, documentType != null ? documentType.getOwnerDocument() : null);
+ public DTDEntityDecl(int start, int end, DOMDocumentType parentDocumentType) {
+ super(start, end, parentDocumentType);
+ }
+
+ public String getPercent() {
+ if(percentStart != null && percentEnd != null) {
+ return "%";
+ }
+ return null;
}
/*
@@ -33,9 +79,20 @@ public DTDEntityDecl(int start, int end, DOMDocumentType documentType) {
*/
@Override
public String getNodeName() {
+ name = getValueFromOffsets(parentDocumentType, name, nameStart, nameEnd);
return name;
}
+ public String getValue() {
+ value = getValueFromOffsets(parentDocumentType, value, valueStart, valueEnd);
+ return value;
+ }
+
+ public String getKind() {
+ kind = getValueFromOffsets(parentDocumentType, kind, kindStart, kindEnd);
+ return kind;
+ }
+
@Override
public short getNodeType() {
return Node.ENTITY_NODE;
@@ -68,7 +125,8 @@ public String getNotationName() {
*/
@Override
public String getPublicId() {
- throw new UnsupportedOperationException();
+ publicId = getValueFromOffsets(parentDocumentType, publicId, publicIdStart, publicIdEnd);
+ return publicId;
}
/*
@@ -78,7 +136,8 @@ public String getPublicId() {
*/
@Override
public String getSystemId() {
- throw new UnsupportedOperationException();
+ systemId = getValueFromOffsets(parentDocumentType, systemId, systemIdStart, systemIdEnd);
+ return systemId;
}
/*
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java
new file mode 100644
index 0000000000..f8b1aaa041
--- /dev/null
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/DTDNotationDecl.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.lsp4xml.dom;
+
+import java.util.ArrayList;
+
+/**
+ * DTDNotationDecl
+ */
+public class DTDNotationDecl extends DTDDeclNode {
+
+ /**
+ * Format:
+ *
+ *
+ *
+ * or
+ *
+ *
+ *
+ * or
+ *
+ *
+ */
+
+ Integer nameStart, nameEnd;
+ Integer kindStart, kindEnd;
+ Integer publicIdStart, publicIdEnd;
+ Integer systemIdStart, systemIdEnd;
+
+ String name;
+ String kind;
+ String publicId;
+ String systemId;
+
+ public DTDNotationDecl(int start, int end, DOMDocumentType parentDocumentType) {
+ super(start, end, parentDocumentType);
+ }
+
+ void setName(int start, int end) {
+ nameStart = start;
+ nameEnd = end;
+ }
+
+ public String getName() {
+ name = getValueFromOffsets(parentDocumentType, name, nameStart, nameEnd);
+ return name;
+ }
+
+ void setKind(int start, int end) {
+ kindStart = start;
+ kindEnd = end;
+ }
+
+ public String getKind() {
+ kind = getValueFromOffsets(parentDocumentType, kind, kindStart, kindEnd);
+ return kind;
+ }
+
+ void setPublicId(int start, int end) {
+ publicIdStart = start;
+ publicIdEnd = end;
+ }
+
+ public String getPublicId() {
+ publicId = getValueFromOffsets(parentDocumentType, publicId, publicIdStart, publicIdEnd);
+ return publicId;
+ }
+
+ void setSystemId(int start, int end) {
+ systemIdStart = start;
+ systemIdEnd = end;
+ }
+
+ public String getSystemId() {
+ systemId = getValueFromOffsets(parentDocumentType, systemId, systemIdStart, systemIdEnd);
+ return systemId;
+ }
+
+ @Override
+ public short getNodeType() {
+ return DOMNode.DTD_NOTATION_DECL;
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java
index 9ea6da3d6d..a223578343 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/Constants.java
@@ -50,6 +50,9 @@ public class Constants {
public final static int _XVL = "x".codePointAt(0);
public final static int _mVL = "m".codePointAt(0);
public final static int _lVL = "l".codePointAt(0);
+ public final static int _PCT = "%".codePointAt(0);
+
+ public static final Pattern ENTITY_NAME_REGEX = Pattern.compile("");
public static final Pattern ELEMENT_NAME_REGEX = Pattern.compile("^[_:\\w][_:\\w-.\\d]*");
@@ -57,21 +60,23 @@ public class Constants {
public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^[^\\s\"'`=<>\\/]+");
- public static final Pattern URL_VALUE_REGEX = Pattern.compile("^\"[^<>\"]*\"");
+ public static final Pattern URL_VALUE_REGEX = Pattern.compile("^(\"|\')[^<>\"]*(\"|\')");
public static final Pattern PROLOG_NAME_OPTIONS = Pattern.compile("^(xml|xml-stylesheet)");
- public static final Pattern DOCTYPE_KIND_OPTIONS = Pattern.compile("^(PUBLIC|SYSTEM)");
+ public static final Pattern DOCTYPE_KIND_OPTIONS = Pattern.compile("^(PUBLIC|SYSTEM)([\\s<>\"'])");
public static final Pattern PI_TAG_NAME = Pattern.compile("^[a-zA-Z0-9]+");
- public static final Pattern DTD_ELEMENT_CATEGORY = Pattern.compile("^(EMPTY|ANY)");
+ public static final Pattern DTD_ELEMENT_CATEGORY = Pattern.compile("^(EMPTY|ANY)([\\s<>\"'])");
+
+ public static final Pattern DTD_ELEMENT_CONTENT = Pattern.compile("^(\\(((\\S,)*(\\S))\\)|\\(\\))");
public static final Pattern DTD_PCDATA = Pattern.compile("^#PCDATA");
- public static final Pattern DTD_ATTLIST_ATTRIBUTE_TYPE = Pattern.compile("^(CDATA|IDREFS|IDREF|ID|NMTOKENS|NMTOKEN|ENTITY|ENTITIES|NOTATION|xml:|\\(.*\\))");
+ public static final Pattern DTD_ATTLIST_ATTRIBUTE_TYPE = Pattern.compile("^(CDATA|IDREFS|IDREF|ID|NMTOKENS|NMTOKEN|ENTITIES|ENTITY|NOTATION|xml:|\\(.*\\))([\\s<>\"'])");
- public static final Pattern DTD_ATTLIST_ATTRIBUTE_VALUE = Pattern.compile("^(#REQUIRED|#IMPLIED|\".*\"|#FIXED \".*\")");
+ public static final Pattern DTD_ATTLIST_ATTRIBUTE_VALUE = Pattern.compile("^(#REQUIRED|#IMPLIED|\".*\"|#FIXED \".*\")([\\s<>\"'])");
public static final Pattern DTD_ENTITY_VALUE = Pattern.compile("^\".*\"");
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/MultiLineStream.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/MultiLineStream.java
index 56cf6e2dd3..7f5d13629e 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/MultiLineStream.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/MultiLineStream.java
@@ -133,6 +133,22 @@ public String advanceIfRegExp(Pattern regex) {
return "";
}
+ /**
+ * Advances stream on regex, but will grab the first group
+ * @param regex
+ * @return
+ */
+ public String advanceIfRegExpGroup1(Pattern regex) {
+ Matcher match = getCachedMatcher(regex);
+ // Initialize start region where search must be started.
+ match.region(this.position, this.len);
+ if (match.find()) {
+ this.position = match.end(1);
+ return match.group(1);
+ }
+ return "";
+ }
+
public String advanceUntilRegExp(Pattern regex) {
String str = this.source.substring(this.position);
/*
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/ScannerState.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/ScannerState.java
index 1777a9a53f..ef95578b65 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/ScannerState.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/ScannerState.java
@@ -22,10 +22,10 @@ public enum ScannerState {
// DTD
DTDWithinDoctype, DTDAfterDoctypeName, DTDAfterDoctypePUBLIC, DTDAfterDoctypeSYSTEM,
- DTDAfterDoctypePublicId, DTDAfterDoctypeSystemId, DTDAfterInternalStartBracket,
-
- DTDWithinContent, DTDWithinElement, DTDWithinAttlist, DTDWithinEntity, DTDAfterElementName, DTDWithinElementContent,
- DTDAfterAttlistName, DTDAfterAttlistDeclName, DTDAfterAttlistElementName, DTDAfterAttlistAttributeName,
- DTDAfterAttlistAttributeType, DTDAfterEntityName, DTDAfterEntityKind, DTDWithinTag;
+ DTDAfterDoctypePublicId,DTDWithinContent, DTDWithinElement, DTDWithinAttlist, DTDWithinEntity,
+ DTDElementAfterName, DTDElementWithinContent, DTDAfterAttlistName, DTDAfterAttlistElementName,
+ DTDAfterAttlistAttributeName, DTDAfterAttlistAttributeType, DTDAfterEntityName, DTDUnrecognizedParameters,
+ DTDWithinNotation, DTDAfterNotationName, DTDAfterNotationPUBLIC, DTDAfterNotationSYSTEM,
+ DTDAfterNotationPublicId, DTDAfterEntityPUBLIC, DTDAfterEntitySYSTEM;
}
\ No newline at end of file
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/TokenType.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/TokenType.java
index 04dda9a6b1..acabb03426 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/TokenType.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/TokenType.java
@@ -53,26 +53,43 @@ public enum TokenType {
DTDStartInternalSubset,
DTDEndInternalSubset,
// DTD Element declaration
- DTDStartElementDecl,
- DTDElementDeclName,
- DTDStartElementContent,
+ DTDStartElement,
+ DTDElementDeclName,
DTDElementCategory,
+ DTDStartElementContent,
+ DTDElementContent,
DTDEndElementContent,
// DTD AttrList declaration
- DTDStartAttlistDecl,
+ DTDStartAttlist,
DTDAttlistElementName,
- DTDAttlistDeclName,
DTDAttlistAttributeValue,
- DTDAttlistType,
+ DTDAttlistAttributeType,
DTDAttlistAttributeName,
// DTD Entity
DTDStartEntity,
+ DTDEntityPercent,
+ DTDEntityKindPUBLIC,
+ DTDEntityKindSYSTEM,
+ DTDEntityPublicId,
+ DTDEntitySystemId,
DTDEntityName,
DTDEntityValue,
- DTDEntityKind,
- DTDEntityURL,
+
+ // DTD Notation
+ DTDStartNotation,
+ DTDNotationName,
+ DTDNotationKindPUBLIC,
+ DTDNotationKindSYSTEM,
+ DTDNotationPublicId,
+ DTDNotationSystemId,
+ //For any DTD Decl Tag that has an unrecognized parameter
+ DTDUnrecognizedParameters,
+
+ //End of any DTD Decl Tag
DTDEndTag;
+
+
}
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java
index 33d5238f3a..fd3f563ef1 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/dom/parser/XMLScanner.java
@@ -10,43 +10,7 @@
*/
package org.eclipse.lsp4xml.dom.parser;
-import static org.eclipse.lsp4xml.dom.parser.Constants.ATTRIBUTE_NAME_REGEX;
-import static org.eclipse.lsp4xml.dom.parser.Constants.ATTRIBUTE_VALUE_REGEX;
-import static org.eclipse.lsp4xml.dom.parser.Constants.DOCTYPE_KIND_OPTIONS;
-import static org.eclipse.lsp4xml.dom.parser.Constants.DTD_ELEMENT_CATEGORY;
-import static org.eclipse.lsp4xml.dom.parser.Constants.ELEMENT_NAME_REGEX;
-import static org.eclipse.lsp4xml.dom.parser.Constants.PI_TAG_NAME;
-import static org.eclipse.lsp4xml.dom.parser.Constants.PROLOG_NAME_OPTIONS;
-import static org.eclipse.lsp4xml.dom.parser.Constants.URL_VALUE_REGEX;
-import static org.eclipse.lsp4xml.dom.parser.Constants._AVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._CAR;
-import static org.eclipse.lsp4xml.dom.parser.Constants._CSB;
-import static org.eclipse.lsp4xml.dom.parser.Constants._CVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._DQO;
-import static org.eclipse.lsp4xml.dom.parser.Constants._DVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._EQS;
-import static org.eclipse.lsp4xml.dom.parser.Constants._EVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._EXL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._FSL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._IVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._LAN;
-import static org.eclipse.lsp4xml.dom.parser.Constants._LVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._MIN;
-import static org.eclipse.lsp4xml.dom.parser.Constants._MVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._NVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._NWL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._ORB;
-import static org.eclipse.lsp4xml.dom.parser.Constants._OSB;
-import static org.eclipse.lsp4xml.dom.parser.Constants._OVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._PVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._QMA;
-import static org.eclipse.lsp4xml.dom.parser.Constants._RAN;
-import static org.eclipse.lsp4xml.dom.parser.Constants._SIQ;
-import static org.eclipse.lsp4xml.dom.parser.Constants._SQO;
-import static org.eclipse.lsp4xml.dom.parser.Constants._SVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._TVL;
-import static org.eclipse.lsp4xml.dom.parser.Constants._WSP;
-import static org.eclipse.lsp4xml.dom.parser.Constants._YVL;
+import static org.eclipse.lsp4xml.dom.parser.Constants.*;
import org.eclipse.lsp4xml.dom.DOMDocumentType.DocumentTypeKind;;
@@ -69,6 +33,19 @@ public class XMLScanner implements Scanner {
String lastDoctypeKind;
String url;
boolean isInsideDTDContent = false; // Either internal dtd in xml file OR external dtd in dtd file
+ boolean isDeclCompleted = false; // If any type of DTD declaration was supplied with all the required properties
+
+ /**
+ * boolean completedInitialAttDef;
+ *
+ * If the first attribute definition was completed in an ATTLIST declaration
+ * eg:
+ *
+ */
+ boolean isInitialAttlistDeclCompleted = false;
private int nbBraceOpened;
public XMLScanner(String input, int initialOffset, ScannerState initialState) {
@@ -91,8 +68,13 @@ String doctypeName() {
return stream.advanceIfRegExp(ATTRIBUTE_NAME_REGEX).toLowerCase();
}
+ /**
+ * Tries to advance off the regex for either 'PUBLIC' or 'SYSTEM'
+ *
+ * @return "PUBLIC" or "SYSTEM" or "" otherwise
+ */
String doctypeKind() {
- return stream.advanceIfRegExp(DOCTYPE_KIND_OPTIONS);
+ return stream.advanceIfRegExpGroup1(DOCTYPE_KIND_OPTIONS);
}
TokenType finishToken(int offset, TokenType type) {
@@ -194,6 +176,7 @@ TokenType internalScan() {
}
if (stream.advanceIfChars(_EXL, _DVL, _OVL, _CVL, _TVL, _YVL, _PVL, _EVL)) { // !DOCTYPE
+ isDeclCompleted = false;
state = ScannerState.DTDWithinDoctype;
return finishToken(offset, TokenType.DTDStartDoctypeTag);
}
@@ -355,7 +338,7 @@ TokenType internalScan() {
case DTDWithinDoctype:
// Possible formats:
// https://en.wikipedia.org/wiki/Document_type_declaration#Syntax
- lastDoctypeKind = null;
+
if (stream.skipWhitespace()) {
return finishToken(offset, TokenType.Whitespace);
}
@@ -369,6 +352,7 @@ TokenType internalScan() {
if (stream.advanceIfChar(_CSB)) { // ]
state = ScannerState.DTDWithinDoctype;
isInsideDTDContent = false;
+ isDeclCompleted = true;
return finishToken(offset, TokenType.DTDEndInternalSubset);
}
@@ -377,13 +361,21 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndDoctypeTag);
}
- String doctypeName = doctypeName();
- if (!doctypeName.equals("")) {
- state = ScannerState.DTDAfterDoctypeName;
- return finishToken(offset, TokenType.DTDDoctypeName);
+ if(stream.peekChar() == _LAN) { // <
+ state = ScannerState.WithinContent;
+ return internalScan();
}
- stream.advanceUntilChar(_RAN); // >
- return finishToken(offset, TokenType.Content);
+
+
+ if (isDeclCompleted == false) {
+ String doctypeName = doctypeName();
+ if(!doctypeName.equals("")) {
+ state = ScannerState.DTDAfterDoctypeName;
+ return finishToken(offset, TokenType.DTDDoctypeName);
+ }
+ }
+ stream.advanceUntilCharOrNewTag(_RAN); // > || <
+ return finishToken(offset, TokenType.DTDUnrecognizedParameters);
case DTDAfterDoctypeName:
if (stream.skipWhitespace()) {
@@ -443,10 +435,6 @@ TokenType internalScan() {
return internalScan();
case DTDWithinContent:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
if (stream.advanceIfChar(_CSB)) { // ]
state = ScannerState.DTDWithinDoctype;
isInsideDTDContent = false;
@@ -454,44 +442,75 @@ TokenType internalScan() {
}
if (stream.advanceIfChar(_LAN)) { // <
+
if (!stream.eos() && stream.peekChar() == _EXL) { // !
+ isDeclCompleted = false;
if (stream.advanceIfChars(_EXL, _EVL, _LVL, _EVL, _MVL, _EVL, _NVL, _TVL)) { // !ELEMENT
state = ScannerState.DTDWithinElement;
- return finishToken(offset, TokenType.DTDStartElementDecl);
+ return finishToken(offset, TokenType.DTDStartElement);
} else if (stream.advanceIfChars(_EXL, _AVL, _TVL, _TVL, _LVL, _IVL, _SVL, _TVL)) { // !ATTLIST
+ isInitialAttlistDeclCompleted = false;
state = ScannerState.DTDWithinAttlist;
- return finishToken(offset, TokenType.DTDStartAttlistDecl);
+ return finishToken(offset, TokenType.DTDStartAttlist);
} else if (stream.advanceIfChars(_EXL, _EVL, _NVL, _TVL, _IVL, _TVL, _YVL)) { // !ENTITY
state = ScannerState.DTDWithinEntity;
return finishToken(offset, TokenType.DTDStartEntity);
+ } else if (stream.advanceIfChars(_EXL, _NVL, _OVL, _TVL, _AVL, _TVL, _IVL, _OVL, _NVL)) { // !NOTATION
+ state = ScannerState.DTDWithinNotation;
+ return finishToken(offset, TokenType.DTDStartNotation);
} else if (stream.advanceIfChars(_EXL, _MIN, _MIN)) { // !-- (for comment)
state = ScannerState.WithinComment;
return finishToken(offset, TokenType.StartCommentTag);
}
}
+ if (stream.advanceUntilCharOrNewTag(_RAN)) { // >
+ stream.advanceIfChar(_RAN); // >
+ return finishToken(offset, TokenType.Content);
+ }
}
- if (stream.advanceUntilChar(_CSB)) { // ]
+ if (stream.advanceIfChar(_CSB)) { // ]
state = ScannerState.DTDWithinDoctype;
isInsideDTDContent = false;
return finishToken(offset, TokenType.DTDEndInternalSubset);
}
- stream.advanceUntilChar(_LAN); // <
+
+ stream.advanceUntilAnyOfChars(_LAN, _CSB); // < || ]
return finishToken(offset, TokenType.Content);
+
+
+ case DTDUnrecognizedParameters:
- case DTDWithinElement:
if (stream.skipWhitespace()) {
return finishToken(offset, TokenType.Whitespace);
}
- if (stream.advanceIfChar(_RAN)) { // >
+ if(stream.advanceIfChar(_RAN)) { // >
state = ScannerState.DTDWithinContent;
return finishToken(offset, TokenType.DTDEndTag);
}
- if (!stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
- state = ScannerState.DTDAfterElementName;
- return finishToken(offset, TokenType.DTDElementDeclName);
+ if(stream.peekChar() == _LAN) { // <
+ state = ScannerState.DTDWithinContent;
+ return internalScan();
+ }
+
+ if(stream.peekChar() == _CSB && isInsideDTDContent) { // ]
+ state = ScannerState.DTDWithinDoctype;
+ return internalScan();
+ }
+
+ if(stream.advanceUntilCharOrNewTag(_RAN)) { // >
+ if(stream.peekChar() == _LAN) { // <
+ state = ScannerState.DTDWithinContent;
+ }
+ }
+ return finishToken(offset, TokenType.DTDUnrecognizedParameters);
+
+
+ case DTDWithinElement:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
}
if (stream.advanceIfChar(_RAN)) { // >
@@ -499,56 +518,75 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- state = ScannerState.DTDWithinContent;
+ if(isDeclCompleted == true) {
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+ }
+
+ if (!stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
+ state = ScannerState.DTDElementAfterName;
+ return finishToken(offset, TokenType.DTDElementDeclName);
+ }
+
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
- case DTDAfterElementName:
- nbBraceOpened = 0;
+ case DTDElementAfterName:
if (stream.skipWhitespace()) {
return finishToken(offset, TokenType.Whitespace);
}
if (stream.advanceIfChar(_ORB)) { // (
- nbBraceOpened++;
- state = ScannerState.DTDWithinElementContent;
+ nbBraceOpened = 1;
+ state = ScannerState.DTDElementWithinContent;
return finishToken(offset, TokenType.DTDStartElementContent);
}
- if (!stream.advanceIfRegExp(DTD_ELEMENT_CATEGORY).equals("")) {
+ if (!stream.advanceIfRegExpGroup1(DTD_ELEMENT_CATEGORY).equals("")) {
+ isDeclCompleted = true;
state = ScannerState.DTDWithinElement;
return finishToken(offset, TokenType.DTDElementCategory);
}
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
- case DTDWithinElementContent:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
+ case DTDElementWithinContent: //
+
+ if(stream.advanceIfChar(_CRB)) { // )
+ isDeclCompleted = true;
+ state = ScannerState.DTDWithinElement;
+ return finishToken(offset, TokenType.DTDEndElementContent);
}
- if (stream.advanceUntilCharOrNewTag(_RAN)) { // >
- if (stream.peekChar() == _LAN) { // <
- state = ScannerState.DTDWithinContent;
- return internalScan();
- } else {
- // current character is '>'
- if (stream.peekChar(-1) == _CSB) {
- // previous character is ']', we can consider we are in the end of doctype.
- stream.advance(-1);
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndElementContent);
+ while(nbBraceOpened > 0) {
+ int c = stream.peekChar();
+
+ if(c == _ORB) { // (
+ nbBraceOpened++;
+ }
+ else if(c == _CRB) { // )
+ nbBraceOpened--;
+ if(nbBraceOpened == 0) {
+ return finishToken(offset, TokenType.DTDElementContent);
}
+ }
+ else if(c == _RAN) { // >
state = ScannerState.DTDWithinElement;
- return finishToken(offset, TokenType.DTDEndElementContent);
+ return finishToken(offset, TokenType.DTDElementContent);
+ }
+ else if(c == _LAN) { // <
+ state = ScannerState.DTDWithinContent;
+ return finishToken(offset, TokenType.DTDElementContent);
}
+ else if(c == -1) {
+ return finishToken(offset, TokenType.DTDElementContent);
+ }
+ stream.advance(1);
}
- return finishToken(offset, TokenType.Unknown);
+
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
case DTDWithinAttlist:
if (stream.skipWhitespace()) {
@@ -560,17 +598,17 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- if (!stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
- state = ScannerState.DTDAfterAttlistElementName;
- return finishToken(offset, TokenType.DTDAttlistElementName);
+ if(isDeclCompleted == true) {
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
}
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
+ if (isInitialAttlistDeclCompleted == false && !stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
+ state = ScannerState.DTDAfterAttlistElementName;
+ return finishToken(offset, TokenType.DTDAttlistElementName);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
case DTDAfterAttlistElementName:
@@ -588,7 +626,7 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
case DTDAfterAttlistAttributeName:
@@ -596,9 +634,9 @@ TokenType internalScan() {
return finishToken(offset, TokenType.Whitespace);
}
- if (!stream.advanceIfRegExp(Constants.DTD_ATTLIST_ATTRIBUTE_TYPE).equals("")) {
+ if (!stream.advanceIfRegExpGroup1(Constants.DTD_ATTLIST_ATTRIBUTE_TYPE).equals("")) {
state = ScannerState.DTDAfterAttlistAttributeType;
- return finishToken(offset, TokenType.DTDAttlistType);
+ return finishToken(offset, TokenType.DTDAttlistAttributeType);
}
if (stream.advanceIfChar(_RAN)) { // >
@@ -606,7 +644,7 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
case DTDAfterAttlistAttributeType:
@@ -614,8 +652,10 @@ TokenType internalScan() {
return finishToken(offset, TokenType.Whitespace);
}
- if (!stream.advanceIfRegExp(Constants.DTD_ATTLIST_ATTRIBUTE_VALUE).equals("")) {
- state = ScannerState.DTDWithinAttlist;
+ if (!stream.advanceIfRegExpGroup1(Constants.DTD_ATTLIST_ATTRIBUTE_VALUE).equals("")) {
+ isInitialAttlistDeclCompleted = true; //we completed the initial attribute declaration
+ isDeclCompleted = true;
+ state = ScannerState.DTDAfterAttlistElementName;
return finishToken(offset, TokenType.DTDAttlistAttributeValue);
}
@@ -624,7 +664,7 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
case DTDWithinEntity:
@@ -637,17 +677,21 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
+ if(isDeclCompleted == true) {
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+ }
+
if (!stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
state = ScannerState.DTDAfterEntityName;
return finishToken(offset, TokenType.DTDEntityName);
}
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
+ if (stream.advanceIfChar(_PCT)) { // %
+ return finishToken(offset, TokenType.DTDEntityPercent);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
case DTDAfterEntityName:
@@ -656,13 +700,36 @@ TokenType internalScan() {
}
if (!stream.advanceIfRegExp(Constants.DTD_ENTITY_VALUE).equals("")) {
+ isDeclCompleted = true;
state = ScannerState.DTDWithinEntity;
return finishToken(offset, TokenType.DTDEntityValue);
}
- if (stream.advanceIfChars(_SVL, _YVL, _SVL, _TVL, _EVL, _MVL)) { // SYSTEM
- state = ScannerState.DTDAfterEntityKind;
- return finishToken(offset, TokenType.DTDEntityKind);
+ lastDoctypeKind = doctypeKind(); // eg: PUBLIC || SYSTEM, will advance the stream if either of these
+ if (lastDoctypeKind.equals(DocumentTypeKind.PUBLIC.name())) {
+ state = ScannerState.DTDAfterEntityPUBLIC;
+ return finishToken(offset, TokenType.DTDEntityKindPUBLIC);
+ } else if (lastDoctypeKind.equals(DocumentTypeKind.SYSTEM.name())) {
+ state = ScannerState.DTDAfterEntitySYSTEM;
+ return finishToken(offset, TokenType.DTDEntityKindSYSTEM);
+ }
+
+ if (stream.advanceIfChar(_RAN)) { // >
+ state = ScannerState.DTDWithinContent;
+ return finishToken(offset, TokenType.DTDEndTag);
+ }
+
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+
+ case DTDAfterEntityPUBLIC:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
+ }
+
+ if (!stream.advanceIfRegExp(URL_VALUE_REGEX).equals("")) {
+ state = ScannerState.DTDAfterEntitySYSTEM;
+ return finishToken(offset, TokenType.DTDEntityPublicId);
}
if (stream.advanceIfChar(_RAN)) { // >
@@ -670,17 +737,18 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
return internalScan();
- case DTDAfterEntityKind:
+ case DTDAfterEntitySYSTEM:
if (stream.skipWhitespace()) {
return finishToken(offset, TokenType.Whitespace);
}
if (!stream.advanceIfRegExp(URL_VALUE_REGEX).equals("")) {
+ isDeclCompleted = true;
state = ScannerState.DTDWithinEntity;
- return finishToken(offset, TokenType.DTDEntityURL);
+ return finishToken(offset, TokenType.DTDEntitySystemId);
}
if (stream.advanceIfChar(_RAN)) { // >
@@ -688,10 +756,96 @@ TokenType internalScan() {
return finishToken(offset, TokenType.DTDEndTag);
}
- state = ScannerState.DTDWithinContent;
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+
+ case DTDWithinNotation:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
+ }
+
+ if(stream.advanceIfChar(_RAN)) { // >
+ state = ScannerState.DTDWithinContent;
+ return finishToken(offset, TokenType.DTDEndTag);
+ }
+
+ if(isDeclCompleted == true) {
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+ }
+
+ if (!stream.advanceIfRegExp(ELEMENT_NAME_REGEX).equals("")) {
+ state = ScannerState.DTDAfterNotationName;
+ return finishToken(offset, TokenType.DTDNotationName);
+ }
+
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+
+ case DTDAfterNotationName:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
+ }
+
+ lastDoctypeKind = doctypeKind(); // eg: PUBLIC || SYSTEM, will advance the stream if either of these
+ if (lastDoctypeKind.equals(DocumentTypeKind.PUBLIC.name())) {
+ state = ScannerState.DTDAfterNotationPUBLIC;
+ return finishToken(offset, TokenType.DTDNotationKindPUBLIC);
+ } else if (lastDoctypeKind.equals(DocumentTypeKind.SYSTEM.name())) {
+ state = ScannerState.DTDAfterNotationSYSTEM;
+ return finishToken(offset, TokenType.DTDNotationKindSYSTEM);
+ }
+
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+
+ case DTDAfterNotationPUBLIC:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
+ }
+ url = stream.advanceIfRegExp(URL_VALUE_REGEX);
+ if (!url.equals("")) {
+ isDeclCompleted = true;
+ state = ScannerState.DTDAfterNotationPublicId;
+ return finishToken(offset, TokenType.DTDNotationPublicId);
+ }
+
+ state = ScannerState.DTDUnrecognizedParameters;
+ return internalScan();
+
+ case DTDAfterNotationSYSTEM:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
+ }
+
+ state = ScannerState.DTDWithinNotation;
+ url = stream.advanceIfRegExp(URL_VALUE_REGEX);
+ if (!url.equals("")) {
+ isDeclCompleted = true;
+ state = ScannerState.DTDAfterNotationName;
+ return finishToken(offset, TokenType.DTDNotationSystemId);
+ }
+ state = ScannerState.DTDWithinNotation;
+ return internalScan();
+
+ case DTDAfterNotationPublicId:
+ if (stream.skipWhitespace()) {
+ return finishToken(offset, TokenType.Whitespace);
+ }
+
+ state = ScannerState.DTDAfterNotationName;
+ url = stream.advanceIfRegExp(URL_VALUE_REGEX); // scan the System Identifier URL
+ if (!url.equals("")) {
+ isDeclCompleted = true;
+ return finishToken(offset, TokenType.DTDNotationSystemId);
+ }
return internalScan();
}
+
+
+
+
stream.advance(1);
state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.WithinContent;
return finishToken(offset, TokenType.Unknown, errorMessage);
diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java
index 3446ae196d..66233e3860 100644
--- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java
+++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/services/XMLSymbolsProvider.java
@@ -28,6 +28,7 @@
import org.eclipse.lsp4xml.dom.DOMNode;
import org.eclipse.lsp4xml.dom.DTDAttlistDecl;
import org.eclipse.lsp4xml.dom.DTDElementDecl;
+import org.eclipse.lsp4xml.dom.DTDNotationDecl;
import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
@@ -92,6 +93,7 @@ private void findDocumentSymbols(DOMNode node, List symbols, Lis
children = hasChildNodes || node.isDTDElementDecl() ? new ArrayList<>() : Collections.emptyList();
DocumentSymbol symbol = new DocumentSymbol(name, getSymbolKind(node), range, selectionRange, null,
children);
+
symbols.add(symbol);
if (node.isDTDElementDecl()) {
// In the case of DTD ELEMENT we try to add in the children the DTD ATTLIST
@@ -155,7 +157,7 @@ private static SymbolKind getSymbolKind(DOMNode node) {
return SymbolKind.Property;
} else if (node.isDoctype()) {
return SymbolKind.Struct;
- } else if (node.isDTDElementDecl() || node.isDTDEntityDecl()) {
+ } else if (node.isDTDElementDecl() || node.isDTDEntityDecl() || node.isDTDNotationDecl()) {
return SymbolKind.Property;
} else if (node.isDTDAttListDecl()) {
return SymbolKind.Key;
@@ -165,7 +167,7 @@ private static SymbolKind getSymbolKind(DOMNode node) {
private static boolean isNodeSymbol(DOMNode node) {
return node.isElement() || node.isDoctype() || node.isProcessingInstruction() || node.isProlog()
- || node.isDTDElementDecl() || node.isDTDAttListDecl() || node.isDTDEntityDecl();
+ || node.isDTDElementDecl() || node.isDTDAttListDecl() || node.isDTDEntityDecl() || node.isDTDNotationDecl();
}
private static String nodeToName(DOMNode node) {
@@ -180,9 +182,12 @@ private static String nodeToName(DOMNode node) {
name = ((DTDElementDecl) node).getName();
} else if (node.isDTDAttListDecl()) {
DTDAttlistDecl attr = (DTDAttlistDecl) node;
- name = attr.getName();
+ name = attr.getAttributeName();
} else if (node.isDTDEntityDecl()) {
name = node.getNodeName();
+ } else if (node.isDTDNotationDecl()) {
+ DTDNotationDecl notation = (DTDNotationDecl) node;
+ name = notation.getName();
}
if (node.hasAttributes()) {
diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserForInternalDTDTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserForInternalDTDTest.java
index e4d569ac09..e088c8f902 100644
--- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserForInternalDTDTest.java
+++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserForInternalDTDTest.java
@@ -89,14 +89,13 @@ public void docTypeNotClosedAndElement() {
String xml = "";
DOMDocument actual = createDOMDocument(xml);
- Assert.assertEquals(1, actual.getChildren().size());
+ Assert.assertEquals(2, actual.getChildren().size());
Assert.assertTrue(actual.getChild(0).isDoctype());
DOMDocumentType documentType = (DOMDocumentType) actual.getChild(0);
Assert.assertEquals(0, documentType.getStart());
- Assert.assertEquals(22, documentType.getEnd());
+ Assert.assertEquals(16, documentType.getEnd());
Assert.assertEquals("foo", documentType.getName());
- Assert.assertTrue(documentType.isClosed()); // here close comes from the '>' of
-
+ Assert.assertTrue(actual.getChild(1).isClosed()); // here close comes from the '>' of
}
@Test
@@ -328,6 +327,7 @@ public void attListDeclNotClosed() {
Assert.assertTrue(actual.getChild(1).isElement());
}
+ //This will fail because the Attribute name regex in Constants.java considers the ']' after 'a' a valid attribute name
@Ignore
@Test
public void attListDeclWithNameNotClosed() {
diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserTest.java
index c3faa30f3c..1a1dcae1e5 100644
--- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserTest.java
+++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/DOMParserTest.java
@@ -12,6 +12,8 @@
import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
+
import org.eclipse.lsp4xml.dom.DOMDocumentType.DocumentTypeKind;
import org.junit.Assert;
import org.junit.Test;
@@ -414,6 +416,288 @@ public void testDoctype2() {
assertDoctype((DOMDocumentType)(document.getChild(0)), 0, 212, "html", DocumentTypeKind.SYSTEM.name(), null, "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", internal);
}
+
+ @Test
+ public void testDTDEntity() {
+ String xml =
+ "\n" +
+ "]>";
+
+ DOMNode doctype = createDoctypeNode(0, 86, 10, 14, null, null, null, null, null, null, 15, 85);
+ doctype.closed = true;
+ DOMNode entity = createEntityDecl(19, 83, 28, 34, null, null, 35, 41, null, null, 42, 82, null, null);
+ entity.closed = true;
+ doctype.addChild(entity);
+
+ DOMDocument document = DOMParser.getInstance().parse(xml, null, null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDAllTypes() {
+ String xml =
+ "\n" +
+ " \n" +
+ " \n" +
+ "] >";
+
+ DOMNode doctype = createDoctypeNode(0, 155, 10, 14, null, null, null, null, null, null, 15, 153);
+ doctype.closed = true;
+ DOMNode entity = createEntityDecl(19, 83, 28, 34, null, null, 35, 41, null, null, 42, 82, null, null);
+ entity.closed = true;
+ DOMNode element = createElementDecl(86, 111, 96, 100, null, null, 101, 110, null, null);
+ element.closed = true;
+ DOMNode attlist = createAttlistDecl(114, 151, 124, 131, 132, 136, 137, 142, 143, 150, null, null);
+ attlist.closed = true;
+
+ doctype.addChild(entity);
+ doctype.addChild(element);
+ doctype.addChild(attlist);
+
+ DOMDocument document = DOMParser.getInstance().parse(xml, null, null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDExternal() {
+ String dtd =
+ "\n" +
+ "\n" +
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 128, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DOMNode entity = createEntityDecl(0, 64, 9, 15, null, null, 16, 22, null, null, 23, 63, null, null);
+ entity.closed = true;
+ DOMNode element = createElementDecl(65, 90, 75, 79, null, null, 80, 89, null, null);
+ element.closed = true;
+ DOMNode attlist = createAttlistDecl(91, 128, 101, 108, 109, 113, 114, 119, 120, 127, null, null);
+ attlist.closed = true;
+
+ doctype.addChild(entity);
+ doctype.addChild(element);
+ doctype.addChild(attlist);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDExternal2() {
+ String dtd =
+ "\n" +
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 95, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DOMNode attlist = createAttlistDecl(0, 41, 10, 25, 26, 28, 29, 31, 32, 40, null, null);
+ attlist.closed = true;
+ DOMNode element = createElementDecl(42, 95, 52, 67, null, null, 68, 94, null, null);
+ element.closed = true;
+
+
+ doctype.addChild(attlist);
+ doctype.addChild(element);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDExternalUnrecognizedParameters() {
+ String dtd =
+ "\n" +
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 81, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DOMNode entity = createEntityDecl(0, 24, 9, 15, null, null, 16, 22, null, null, null, null, null, null);
+ entity.closed = true;
+ DOMNode element = createElementDecl(25, 49, 35, 39, null, null, 40, 49, null, null);
+ element.closed = false;
+ DOMNode attlist = createAttlistDecl(50, 81, 60, 67, 68, 72, null, null, null, null, 73, 80);
+ attlist.closed = true;
+
+ doctype.addChild(entity);
+ doctype.addChild(element);
+ doctype.addChild(attlist);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDExternalUnrecognizedParameters2() {
+ String dtd =
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 81, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DOMNode entity = createEntityDecl(0, 24, 9, 15, null, null, 16, 22, null, null, null, null, null, null);
+ entity.closed = false;
+ DOMNode element = createElementDecl(25, 49, 35, 39, null, null, 40, 49, null, null);
+ element.closed = false;
+ DOMNode attlist = createAttlistDecl(50, 81, 60, 67, 68, 72, null, null, null, null, 73, 80);
+ attlist.closed = true;
+
+ doctype.addChild(entity);
+ doctype.addChild(element);
+ doctype.addChild(attlist);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDExternalUnrecognizedParameters3() {
+ String dtd =
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 32, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DOMNode attlist = createAttlistDecl(0, 15, 10, 14, null, null, null, null, null, null, null, null);
+ attlist.closed = false;
+ DOMNode element = createElementDecl(16, 32, 26, 30, null, null, null, null, null, null);
+ element.closed = true;
+
+
+ doctype.addChild(attlist);
+ doctype.addChild(element);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testDTDExternalElementContentUnclosed() {
+ String dtd =
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 23, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+
+ DOMNode element = createElementDecl(0, 23, 10, 14, null, null, 15, 22, null, null);
+ element.closed = true;
+
+ doctype.addChild(element);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+
+ }
+
+ @Test
+ public void testATTLISTMultipleInternal() {
+ String dtd =
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 70, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DTDAttlistDecl attlist = createAttlistDecl(0, 70, 10, 21, 26, 28, 29, 34, 35, 44, null, null);
+ attlist.closed = true;
+ DTDAttlistDecl attlistInternal = createAttlistDecl(-1, -1, null, null, 49, 53, 54, 59, 60, 69, null, null);
+ attlistInternal.closed = true;
+
+ doctype.addChild(attlist);
+ attlist.addAdditionalAttDecl(attlistInternal);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+ }
+
+ @Test
+ public void testNotation() {
+ String dtd =
+ "\n" +
+ "\n" +
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 112, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DTDNotationDecl notation1 = createNotationDecl(0, 32, 11, 14, 15, 21, 22, 31, null, null, null, null);
+ notation1.closed = true;
+ DTDNotationDecl notation2 = createNotationDecl(33, 77, 44, 47, 48, 54, 55, 64, 65, 76, null, null);
+ notation2.closed = true;
+ DTDNotationDecl notation3 = createNotationDecl(78, 112, 89, 92, 93, 99, null, null, 100, 111, null, null);
+ notation3.closed = true;
+
+ doctype.addChild(notation1);
+ doctype.addChild(notation2);
+ doctype.addChild(notation3);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+ }
+
+ @Test
+ public void testNotationMissingEndTag() {
+ String dtd =
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 77, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DTDNotationDecl notation1 = createNotationDecl(0, 32, 11, 14, 15, 21, 22, 32, null, null, null, null);
+ notation1.closed = false;
+ DTDNotationDecl notation2 = createNotationDecl(33, 77, 44, 47, 48, 54, 55, 64, 65, 76, null, null);
+ notation2.closed = true;
+
+ doctype.addChild(notation1);
+ doctype.addChild(notation2);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+ }
+
+ @Test
+ public void testNotationMissingEndTagMissingAndExtraValues() {
+ String dtd =
+ "";
+
+ DOMNode doctype = createDoctypeNode(0, 81, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DTDNotationDecl notation1 = createNotationDecl(0, 32, 11, 14, 15, 21, 22, 32, null, null, null, null);
+ notation1.closed = false;
+ DTDNotationDecl notation2 = createNotationDecl(33, 81, 44, 47, 48, 54, 55, 64, 65, 76, 77, 80);
+ notation2.closed = true;
+
+ doctype.addChild(notation1);
+ doctype.addChild(notation2);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+ }
+
+ @Test
+ public void testUnrecognizedDTDTagName() {
+ String dtd = "";
+
+ DOMNode doctype = createDoctypeNode(0, 48, null, null, null, null, null, null, null, null, null, null);
+ doctype.closed = true;
+ DOMText text = createTextNode("", 0, 48, true);
+
+ doctype.addChild(text);
+
+ DOMDocument document = DOMParser.getInstance().parse(dtd, "name.dtd", null);
+ compareTrees(doctype, document.getChild(0));
+ }
+
// --------------------------------------------------------------------------------
// Tools
@@ -454,6 +738,89 @@ private static DOMElement createElement(String tag, int start, Integer endTagSta
return (DOMElement) createNode(DOMNode.ELEMENT_NODE, tag, start, endTagStart, end, closed);
}
+ private static DTDAttlistDecl createAttlistDecl(int start, int end, Integer elementNameStart, Integer elementNameEnd, Integer attributeNameStart,
+ Integer attributeNameEnd, Integer attributeTypeStart, Integer attributeTypeEnd, Integer attributeValueStart, Integer attributeValueEnd,
+ Integer unrecognizedStart, Integer unrecognizedEnd) {
+ DTDAttlistDecl attlist = new DTDAttlistDecl(start, end, null);
+ attlist.elementNameStart = elementNameStart;
+ attlist.elementNameEnd = elementNameEnd;
+ attlist.attributeNameStart = attributeNameStart;
+ attlist.attributeNameEnd = attributeNameEnd;
+ attlist.attributeTypeStart = attributeTypeStart;
+ attlist.attributeTypeEnd = attributeTypeEnd;
+ attlist.attributeValueStart = attributeValueStart;
+ attlist.attributeValueEnd = attributeValueEnd;
+ attlist.unrecognizedStart = unrecognizedStart;
+ attlist.unrecognizedEnd = unrecognizedEnd;
+ return attlist;
+ }
+
+ private static DTDElementDecl createElementDecl(int start, int end, Integer nameStart, Integer nameEnd, Integer categoryStart,
+ Integer categoryEnd, Integer contentStart, Integer contentEnd, Integer unrecognizedStart, Integer unrecognizedEnd) {
+ DTDElementDecl element = new DTDElementDecl(start, end, null);
+ element.nameStart = nameStart;
+ element.nameEnd = nameEnd;
+ element.categoryStart = categoryStart;
+ element.categoryEnd = categoryEnd;
+ element.contentStart = contentStart;
+ element.contentEnd = contentEnd;
+ element.unrecognizedStart = unrecognizedStart;
+ element.unrecognizedEnd = unrecognizedEnd;
+ return element;
+ }
+
+ private static DTDEntityDecl createEntityDecl(int start, int end, Integer nameStart, Integer nameEnd, Integer valueStart,
+ Integer valueEnd, Integer kindStart, Integer kindEnd, Integer publicIdStart, Integer publicIdEnd, Integer systemIdStart,
+ Integer systemIdEnd, Integer unrecognizedStart, Integer unrecognizedEnd) {
+ DTDEntityDecl entity = new DTDEntityDecl(start, end, null);
+ entity.nameStart = nameStart;
+ entity.nameEnd = nameEnd;
+ entity.valueStart = valueStart;
+ entity.valueEnd = valueEnd;
+ entity.kindStart = kindStart;
+ entity.kindEnd = kindEnd;
+ entity.publicIdStart = publicIdStart;
+ entity.publicIdEnd = publicIdEnd;
+ entity.systemIdStart = systemIdStart;
+ entity.systemIdEnd = systemIdEnd;
+ entity.unrecognizedStart = unrecognizedStart;
+ entity.unrecognizedEnd = unrecognizedEnd;
+ return entity;
+ }
+
+ private static DTDNotationDecl createNotationDecl(int start, int end, Integer nameStart, Integer nameEnd, Integer kindStart, Integer kindEnd,
+ Integer publicIdStart, Integer publicIdEnd, Integer systemIdStart, Integer systemIdEnd, Integer unrecognizedStart, Integer unrecognizedEnd) {
+ DTDNotationDecl notation = new DTDNotationDecl(start, end, null);
+ notation.nameStart = nameStart;
+ notation.nameEnd = nameEnd;
+ notation.kindStart = kindStart;
+ notation.kindEnd = kindEnd;
+ notation.publicIdStart = publicIdStart;
+ notation.publicIdEnd = publicIdEnd;
+ notation.systemIdStart = systemIdStart;
+ notation.systemIdEnd = systemIdEnd;
+ notation.unrecognizedStart = unrecognizedStart;
+ notation.unrecognizedEnd = unrecognizedEnd;
+ return notation;
+ }
+
+ private static DOMDocumentType createDoctypeNode(int start, int end, Integer nameStart, Integer nameEnd, Integer kindStart,
+ Integer kindEnd, Integer publicIdStart, Integer publicIdEnd, Integer systemIdStart, Integer systemIdEnd,
+ Integer internalSubsetStart, Integer internalSubsetEnd) {
+ DOMDocumentType doctype = new DOMDocumentType(start, end, null);
+ doctype.nameStart = nameStart;
+ doctype.nameEnd = nameEnd;
+ doctype.kindStart = kindStart;
+ doctype.kindEnd = kindEnd;
+ doctype.publicIdStart = publicIdStart;
+ doctype.publicIdEnd = publicIdEnd;
+ doctype.systemIdStart = systemIdStart;
+ doctype.systemIdEnd = systemIdEnd;
+ doctype.internalSubsetStart = internalSubsetStart;
+ doctype.internalSubsetEnd = internalSubsetEnd;
+ return doctype;
+ }
+
private static DOMNode createNode(short nodeType, String tag, int start, Integer endTagStart, int end,
boolean closed) {
DOMNode n = createNode(nodeType, start, end);
@@ -595,6 +962,105 @@ private static void compareTrees(DOMNode expectedNode, DOMNode actualNode) {
if (expectedNode.isCharacterData()) {
assertEquals(((DOMCharacterData) expectedNode).getData(), ((DOMCharacterData) actualNode).getData());
}
+
+ if (expectedNode.isDTDAttListDecl()) {
+ assertEquals(true, actualNode.isDTDAttListDecl());
+ DTDAttlistDecl expectedTemp = (DTDAttlistDecl) expectedNode;
+ DTDAttlistDecl actualTemp = (DTDAttlistDecl) actualNode;
+ assertEquals(expectedTemp.elementNameStart, actualTemp.elementNameStart);
+ assertEquals(expectedTemp.elementNameEnd, actualTemp.elementNameEnd);
+ assertEquals(expectedTemp.attributeNameStart, actualTemp.attributeNameStart);
+ assertEquals(expectedTemp.attributeNameEnd, actualTemp.attributeNameEnd);
+ assertEquals(expectedTemp.attributeTypeStart, actualTemp.attributeTypeStart);
+ assertEquals(expectedTemp.attributeTypeEnd, actualTemp.attributeTypeEnd);
+ assertEquals(expectedTemp.attributeValueStart, actualTemp.attributeValueStart);
+ assertEquals(expectedTemp.attributeValueEnd, actualTemp.attributeValueEnd);
+ assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart);
+ assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd);
+
+ ArrayList expectedInternalChildren = expectedTemp.getInternalChildren();
+ ArrayList actualInternalChildren = actualTemp.getInternalChildren();
+ assertEquals(expectedInternalChildren == null, actualInternalChildren == null);
+ if(expectedInternalChildren != null) {
+ assertEquals(expectedInternalChildren.size(), actualInternalChildren.size());
+ for (int i = 0; i < expectedTemp.getInternalChildren().size(); i++) {
+ assertInternalAttlist(expectedInternalChildren.get(i), actualInternalChildren.get(i));
+ }
+ }
+ }
+
+ if(expectedNode.isDTDElementDecl()) {
+ assertEquals(true, actualNode.isDTDElementDecl());
+ DTDElementDecl expectedTemp = (DTDElementDecl) expectedNode;
+ DTDElementDecl actualTemp = (DTDElementDecl) actualNode;
+ assertEquals(expectedTemp.nameStart, actualTemp.nameStart);
+ assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd);
+ assertEquals(expectedTemp.categoryStart, actualTemp.categoryStart);
+ assertEquals(expectedTemp.categoryEnd, actualTemp.categoryEnd);
+ assertEquals(expectedTemp.contentStart, actualTemp.contentStart);
+ assertEquals(expectedTemp.contentEnd, actualTemp.contentEnd);
+ assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart);
+ assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd);
+ }
+
+ else if(expectedNode.isDTDEntityDecl()) {
+ assertEquals(true, actualNode.isDTDEntityDecl());
+ DTDEntityDecl expectedTemp = (DTDEntityDecl) expectedNode;
+ DTDEntityDecl actualTemp = (DTDEntityDecl) actualNode;
+ assertEquals(expectedTemp.nameStart, actualTemp.nameStart);
+ assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd);
+ assertEquals(expectedTemp.valueStart, actualTemp.valueStart);
+ assertEquals(expectedTemp.valueEnd, actualTemp.valueEnd);
+ assertEquals(expectedTemp.kindStart, actualTemp.kindStart);
+ assertEquals(expectedTemp.kindEnd, actualTemp.kindEnd);
+ assertEquals(expectedTemp.publicIdStart, actualTemp.publicIdStart);
+ assertEquals(expectedTemp.publicIdEnd, actualTemp.publicIdEnd);
+ assertEquals(expectedTemp.systemIdStart, actualTemp.systemIdStart);
+ assertEquals(expectedTemp.systemIdEnd, actualTemp.systemIdEnd);
+ assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart);
+ assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd);
+ }
+
+ else if(expectedNode.isDTDNotationDecl()) {
+ assertEquals(true, actualNode.isDTDNotationDecl());
+ DTDNotationDecl expectedTemp = (DTDNotationDecl) expectedNode;
+ DTDNotationDecl actualTemp = (DTDNotationDecl) actualNode;
+ assertEquals(expectedTemp.nameStart, actualTemp.nameStart);
+ assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd);
+ assertEquals(expectedTemp.kindStart, actualTemp.kindStart);
+ assertEquals(expectedTemp.kindEnd, actualTemp.kindEnd);
+ assertEquals(expectedTemp.publicIdStart, actualTemp.publicIdStart);
+ assertEquals(expectedTemp.publicIdEnd, actualTemp.publicIdEnd);
+ assertEquals(expectedTemp.systemIdStart, actualTemp.systemIdStart);
+ assertEquals(expectedTemp.systemIdEnd, actualTemp.systemIdEnd);
+ assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart);
+ assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd);
+ }
+
+ else if(expectedNode.isDoctype()) {
+ assertEquals(true, actualNode.isDoctype());
+ DOMDocumentType expectedTemp = (DOMDocumentType) expectedNode;
+ DOMDocumentType actualTemp = (DOMDocumentType) actualNode;
+ assertEquals(expectedTemp.nameStart, actualTemp.nameStart);
+ assertEquals(expectedTemp.nameEnd, actualTemp.nameEnd);
+ assertEquals(expectedTemp.kindStart, actualTemp.kindStart);
+ assertEquals(expectedTemp.kindEnd, actualTemp.kindEnd);
+ assertEquals(expectedTemp.publicIdStart, actualTemp.publicIdStart);
+ assertEquals(expectedTemp.publicIdEnd, actualTemp.publicIdEnd);
+ assertEquals(expectedTemp.systemIdStart, actualTemp.systemIdStart);
+ assertEquals(expectedTemp.systemIdEnd, actualTemp.systemIdEnd);
+ assertEquals(expectedTemp.internalSubsetStart, actualTemp.internalSubsetStart);
+ assertEquals(expectedTemp.internalSubsetEnd, actualTemp.internalSubsetEnd);
+ }
+
+ else if(expectedNode.isGenericDTDDecl()) {
+ DTDDeclNode expectedTemp = (DTDDeclNode) expectedNode;
+ DTDDeclNode actualTemp = (DTDDeclNode) actualNode;
+
+ assertEquals(expectedTemp.unrecognizedStart, actualTemp.unrecognizedStart);
+ assertEquals(expectedTemp.unrecognizedEnd, actualTemp.unrecognizedEnd);
+ }
+
assertEquals(expectedNode.isClosed(), actualNode.isClosed());
assertEquals(expectedNode.isCDATA(), actualNode.isCDATA());
assertEquals(expectedNode.isProcessingInstruction(), actualNode.isProcessingInstruction());
@@ -606,6 +1072,26 @@ private static void compareTrees(DOMNode expectedNode, DOMNode actualNode) {
}
}
+ public static void assertInternalAttlist(DTDAttlistDecl expected, DTDAttlistDecl actual) {
+ assertEquals(expected.attributeNameStart, actual.attributeNameStart);
+ assertEquals(expected.attributeNameEnd, actual.attributeNameEnd);
+ assertEquals(expected.attributeTypeStart, actual.attributeTypeStart);
+ assertEquals(expected.attributeTypeEnd, actual.attributeTypeEnd);
+ assertEquals(expected.attributeValueStart, actual.attributeValueStart);
+ assertEquals(expected.attributeValueEnd, actual.attributeValueEnd);
+ }
+
+ public static void assertInternalNotation(DTDNotationDecl expected, DTDNotationDecl actual) {
+ assertEquals(expected.nameStart, actual.nameStart);
+ assertEquals(expected.nameEnd, actual.nameEnd);
+ assertEquals(expected.kindStart, actual.kindStart);
+ assertEquals(expected.kindEnd, actual.kindEnd);
+ assertEquals(expected.publicIdStart, actual.publicIdStart);
+ assertEquals(expected.publicIdEnd, actual.publicIdEnd);
+ assertEquals(expected.systemIdStart, actual.systemIdStart);
+ assertEquals(expected.systemIdEnd, actual.systemIdEnd);
+ }
+
public void insertIntoAttributes(DOMNode n, String key, String value) {
n.setAttribute(key, value);
}
diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForExternalDTDTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForExternalDTDTest.java
index 73f5bc8805..fb9857c005 100644
--- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForExternalDTDTest.java
+++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForExternalDTDTest.java
@@ -30,7 +30,7 @@ public void testDocumentTypeExternalOnly() {
"";
scanner = XMLScanner.createScanner(dtd, true);
// assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
- assertOffsetAndToken(0, TokenType.Whitespace);
+ assertOffsetAndToken(0, TokenType.Content);
// assertOffsetAndToken(19, TokenType.DTDDoctypeName);
// assertOffsetAndToken(14, TokenType.Whitespace);
// assertOffsetAndToken(15, TokenType.DTDStartInternalSubset);
@@ -41,21 +41,21 @@ public void testDocumentTypeExternalOnly() {
assertOffsetAndToken(32, TokenType.Whitespace);
assertOffsetAndToken(33, TokenType.DTDEntityValue);
assertOffsetAndToken(41, TokenType.DTDEndTag);
- assertOffsetAndToken(42, TokenType.Whitespace);
+ assertOffsetAndToken(42, TokenType.Content);
assertOffsetAndToken(46, TokenType.DTDStartEntity);
assertOffsetAndToken(54, TokenType.Whitespace);
assertOffsetAndToken(55, TokenType.DTDEntityName);
assertOffsetAndToken(61, TokenType.Whitespace);
assertOffsetAndToken(62, TokenType.DTDEntityValue);
assertOffsetAndToken(84, TokenType.DTDEndTag);
- assertOffsetAndToken(85, TokenType.Whitespace);
+ assertOffsetAndToken(85, TokenType.Content);
// assertOffsetAndToken(86, TokenType.DTDEndInternalSubset);
// assertOffsetAndToken(87, TokenType.DTDEndDoctypeTag);
}
@Test
- public void elementDeclWithServeralBraces() {
+ public void elementDeclWithSeveralBraces() {
String dtd = "";
scanner = XMLScanner.createScanner(dtd, true);
// assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
@@ -64,12 +64,13 @@ public void elementDeclWithServeralBraces() {
// assertOffsetAndToken(14, TokenType.Whitespace);
// assertOffsetAndToken(15, TokenType.DTDStartInternalSubset);
// assertOffsetAndToken(16, TokenType.Whitespace);
- assertOffsetAndToken(0, TokenType.DTDStartElementDecl);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
assertOffsetAndToken(9, TokenType.Whitespace);
assertOffsetAndToken(10, TokenType.DTDElementDeclName);
assertOffsetAndToken(20, TokenType.Whitespace);
assertOffsetAndToken(21, TokenType.DTDStartElementContent);
- assertOffsetAndToken(22, TokenType.DTDEndElementContent);
+ assertOffsetAndToken(22, TokenType.DTDElementContent);
+ assertOffsetAndToken(61, TokenType.DTDEndElementContent);
assertOffsetAndToken(62, TokenType.DTDEndTag);
assertOffsetAndToken(63, TokenType.EOS);
@@ -78,6 +79,651 @@ public void elementDeclWithServeralBraces() {
}
+ @Test
+ public void notationDeclNormal() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDNotationPublicId);
+ assertOffsetAndToken(31, TokenType.Whitespace);
+ assertOffsetAndToken(32, TokenType.DTDNotationSystemId);
+ assertOffsetAndToken(43, TokenType.DTDEndTag);
+ assertOffsetAndToken(44, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclMissingSystemId() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDNotationPublicId);
+ assertOffsetAndToken(31, TokenType.DTDEndTag);
+ assertOffsetAndToken(32, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclMissingKind() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(36, TokenType.DTDEndTag);
+ assertOffsetAndToken(37, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclIncorrectURLParameter() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(30, TokenType.DTDEndTag);
+ assertOffsetAndToken(31, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclUnclosed() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(30, TokenType.DTDStartElement);
+ assertOffsetAndToken(39, TokenType.DTDEndTag);
+ assertOffsetAndToken(40, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclUnclosed2() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDStartElement);
+ assertOffsetAndToken(31, TokenType.DTDEndTag);
+ assertOffsetAndToken(32, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclUnclosed3() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDStartElement);
+ assertOffsetAndToken(24, TokenType.DTDEndTag);
+ assertOffsetAndToken(25, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclUnclosed4() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDNotationPublicId);
+ assertOffsetAndToken(31, TokenType.Whitespace);
+ assertOffsetAndToken(32, TokenType.DTDNotationSystemId);
+ assertOffsetAndToken(43, TokenType.DTDStartElement);
+ assertOffsetAndToken(52, TokenType.DTDEndTag);
+ assertOffsetAndToken(53, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclNormalMoreSpaces() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(23, TokenType.Whitespace);
+ assertOffsetAndToken(24, TokenType.DTDNotationPublicId);
+ assertOffsetAndToken(33, TokenType.Whitespace);
+ assertOffsetAndToken(36, TokenType.DTDNotationSystemId);
+ assertOffsetAndToken(47, TokenType.Whitespace);
+ assertOffsetAndToken(48, TokenType.DTDEndTag);
+ assertOffsetAndToken(49, TokenType.EOS);
+ }
+
+ @Test
+ public void notationDeclUnrecognizedContent() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDNotationName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDNotationKindPUBLIC);
+ assertOffsetAndToken(23, TokenType.Whitespace);
+ assertOffsetAndToken(24, TokenType.DTDNotationPublicId);
+ assertOffsetAndToken(33, TokenType.Whitespace);
+ assertOffsetAndToken(36, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(38, TokenType.DTDEndTag);
+ assertOffsetAndToken(39, TokenType.EOS);
+ }
+
+ @Test
+ public void notationNoParameters() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartNotation);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDStartElement);
+ assertOffsetAndToken(20, TokenType.Whitespace);
+ assertOffsetAndToken(21, TokenType.DTDEndTag);
+ assertOffsetAndToken(22, TokenType.EOS);
+ }
+
+ @Test
+ public void elementDeclContent() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDElementDeclName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDStartElementContent);
+ assertOffsetAndToken(16, TokenType.DTDElementContent);
+ assertOffsetAndToken(36, TokenType.DTDEndElementContent);
+ assertOffsetAndToken(37, TokenType.DTDEndTag);
+ assertOffsetAndToken(38, TokenType.EOS);
+ }
+
+ @Test
+ public void elementOnlyName() {
+ String dtd = " ";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDElementDeclName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEndTag);
+ assertOffsetAndToken(16, TokenType.Content);
+ assertOffsetAndToken(17, TokenType.DTDStartEntity);
+ assertOffsetAndToken(25, TokenType.DTDEndTag);
+ assertOffsetAndToken(26, TokenType.EOS);
+ }
+
+ @Test
+ public void elementUnclosed() {
+ String dtd = " ";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDElementDeclName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDElementCategory);
+ assertOffsetAndToken(20, TokenType.DTDEndTag);
+ assertOffsetAndToken(21, TokenType.Content);
+ assertOffsetAndToken(22, TokenType.DTDStartEntity);
+ assertOffsetAndToken(30, TokenType.DTDEndTag);
+ assertOffsetAndToken(31, TokenType.EOS);
+ }
+
+ @Test
+ public void elementDeclCategory() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDElementDeclName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDElementCategory);
+ assertOffsetAndToken(18, TokenType.DTDEndTag);
+ assertOffsetAndToken(19, TokenType.EOS);
+ }
+
+ @Test
+ public void elementDeclContentIncomplete() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDElementDeclName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDStartElementContent);
+ assertOffsetAndToken(16, TokenType.DTDElementContent);
+ assertOffsetAndToken(32, TokenType.DTDEndTag);
+ assertOffsetAndToken(33, TokenType.EOS);
+ }
+
+ @Test
+ public void elementDeclContentIncompleteAndUnclosed() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDElementDeclName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDStartElementContent);
+ assertOffsetAndToken(16, TokenType.DTDElementContent);
+ assertOffsetAndToken(32, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(41, TokenType.Whitespace);
+ assertOffsetAndToken(42, TokenType.DTDEndTag);
+ assertOffsetAndToken(43, TokenType.EOS);
+ }
+
+ @Test
+ public void elementNoParameters() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(12, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDEndTag);
+ assertOffsetAndToken(23, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistDecl() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(24, TokenType.Whitespace);
+ assertOffsetAndToken(25, TokenType.DTDAttlistAttributeType);
+ assertOffsetAndToken(30, TokenType.Whitespace);
+ assertOffsetAndToken(31, TokenType.DTDAttlistAttributeValue);
+ assertOffsetAndToken(43, TokenType.DTDEndTag);
+ assertOffsetAndToken(44, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistMultipleDecls() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(30, TokenType.Whitespace);
+ assertOffsetAndToken(31, TokenType.DTDAttlistAttributeType);
+ assertOffsetAndToken(36, TokenType.Whitespace);
+ assertOffsetAndToken(37, TokenType.DTDAttlistAttributeValue);
+ assertOffsetAndToken(50, TokenType.Whitespace);
+ assertOffsetAndToken(55, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(63, TokenType.Whitespace);
+ assertOffsetAndToken(64, TokenType.DTDAttlistAttributeType);
+ assertOffsetAndToken(69, TokenType.Whitespace);
+ assertOffsetAndToken(70, TokenType.DTDAttlistAttributeValue);
+ assertOffsetAndToken(83, TokenType.DTDEndTag);
+ assertOffsetAndToken(84, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistIncompleteDecl() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(30, TokenType.Whitespace);
+ assertOffsetAndToken(31, TokenType.DTDAttlistAttributeType);
+ assertOffsetAndToken(36, TokenType.Whitespace);
+ assertOffsetAndToken(42, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(70, TokenType.DTDEndTag);
+ assertOffsetAndToken(71, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistMissingAttributeName() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(22, TokenType.Whitespace);
+ assertOffsetAndToken(23, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(31, TokenType.DTDEndTag);
+ assertOffsetAndToken(32, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistMissingAttributeType() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(24, TokenType.Whitespace);
+ assertOffsetAndToken(25, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(33, TokenType.DTDEndTag);
+ assertOffsetAndToken(34, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistMissingAttributeValue() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(24, TokenType.Whitespace);
+ assertOffsetAndToken(25, TokenType.DTDAttlistAttributeType);
+ assertOffsetAndToken(30, TokenType.Whitespace);
+ assertOffsetAndToken(31, TokenType.DTDEndTag);
+ assertOffsetAndToken(32, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistNoParameters() {
+ String dtd = "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDStartElement);
+ assertOffsetAndToken(19, TokenType.Whitespace);
+ assertOffsetAndToken(20, TokenType.DTDEndTag);
+ assertOffsetAndToken(21, TokenType.EOS);
+ }
+
+ @Test
+ public void attlistMissingAttributeNameAndEndBracket() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDAttlistElementName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDAttlistAttributeName);
+ assertOffsetAndToken(24, TokenType.Whitespace);
+ assertOffsetAndToken(25, TokenType.DTDAttlistAttributeType);
+ assertOffsetAndToken(30, TokenType.Whitespace);
+ assertOffsetAndToken(31, TokenType.DTDAttlistAttributeValue);
+ assertOffsetAndToken(43, TokenType.Whitespace);
+ assertOffsetAndToken(44, TokenType.DTDStartElement);
+ assertOffsetAndToken(53, TokenType.DTDEndTag);
+ assertOffsetAndToken(54, TokenType.EOS);
+ }
+
+ @Test
+ public void entityPUBLIC() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDEntityPublicId);
+ assertOffsetAndToken(33, TokenType.Whitespace);
+ assertOffsetAndToken(34, TokenType.DTDEntitySystemId);
+ assertOffsetAndToken(45, TokenType.Whitespace);
+ assertOffsetAndToken(46, TokenType.DTDEndTag);
+ assertOffsetAndToken(47, TokenType.EOS);
+ }
+
+ @Test
+ public void entitySYSTEM() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityKindSYSTEM);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(24, TokenType.DTDEntitySystemId);
+ assertOffsetAndToken(35, TokenType.Whitespace);
+ assertOffsetAndToken(36, TokenType.DTDEndTag);
+ assertOffsetAndToken(37, TokenType.EOS);
+ }
+
+ @Test
+ public void entityCorrect() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityValue);
+ assertOffsetAndToken(23, TokenType.Whitespace);
+ assertOffsetAndToken(24, TokenType.DTDEndTag);
+ assertOffsetAndToken(25, TokenType.EOS);
+ }
+
+ @Test
+ public void entityCorrectWithPercent() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityPercent);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDEntityName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDEntityValue);
+ assertOffsetAndToken(25, TokenType.Whitespace);
+ assertOffsetAndToken(26, TokenType.DTDEndTag);
+ assertOffsetAndToken(27, TokenType.EOS);
+ }
+
+ @Test
+ public void entityCorrectWithPercentAndPublic() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityPercent);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDEntityName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(23, TokenType.Whitespace);
+ assertOffsetAndToken(24, TokenType.DTDEntityPublicId);
+ assertOffsetAndToken(34, TokenType.Whitespace);
+ assertOffsetAndToken(35, TokenType.DTDEntitySystemId);
+ assertOffsetAndToken(45, TokenType.Whitespace);
+ assertOffsetAndToken(46, TokenType.DTDEndTag);
+ assertOffsetAndToken(47, TokenType.EOS);
+ }
+
+ @Test
+ public void entityIncorrectWithPercentAndPublic() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityPercent);
+ assertOffsetAndToken(10, TokenType.Whitespace);
+ assertOffsetAndToken(11, TokenType.DTDEntityName);
+ assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(17, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(23, TokenType.Whitespace);
+ assertOffsetAndToken(24, TokenType.DTDEntityPublicId);
+ assertOffsetAndToken(34, TokenType.Whitespace);
+ assertOffsetAndToken(35, TokenType.DTDEntitySystemId);
+ assertOffsetAndToken(45, TokenType.Whitespace);
+ assertOffsetAndToken(46, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(53, TokenType.DTDEndTag);
+ assertOffsetAndToken(54, TokenType.EOS);
+ }
+
+ @Test
+ public void entityIncorrectMissingSystemId() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDEntityPublicId);
+ assertOffsetAndToken(32, TokenType.Whitespace);
+ assertOffsetAndToken(33, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(35, TokenType.DTDEndTag);
+ assertOffsetAndToken(36, TokenType.EOS);
+ }
+
+ @Test
+ public void entityIncorrectMissingSystemIdUnclosed() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDEntityPublicId);
+ assertOffsetAndToken(32, TokenType.Whitespace);
+ assertOffsetAndToken(33, TokenType.DTDStartElement);
+ assertOffsetAndToken(42, TokenType.DTDEndTag);
+ assertOffsetAndToken(43, TokenType.EOS);
+ }
+
+ @Test
+ public void entityIncorrectMissingIDs() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(24, TokenType.DTDEndTag);
+ assertOffsetAndToken(25, TokenType.EOS);
+ }
+
+ @Test
+ public void entityIncorrect() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.DTDStartEntity);
+ assertOffsetAndToken(8, TokenType.Whitespace);
+ assertOffsetAndToken(9, TokenType.DTDEntityName);
+ assertOffsetAndToken(14, TokenType.Whitespace);
+ assertOffsetAndToken(15, TokenType.DTDEntityKindPUBLIC);
+ assertOffsetAndToken(21, TokenType.Whitespace);
+ assertOffsetAndToken(22, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(25, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(34, TokenType.DTDEndTag);
+ assertOffsetAndToken(35, TokenType.EOS);
+ }
+
+
+ @Test
+ public void dtdUnrecognizedTagName() {
+ String dtd =
+ "";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.Content);
+ assertOffsetAndToken(25, TokenType.EOS);
+ }
+
+ @Test
+ public void dtdUnrecognizedTagName2() {
+ String dtd =
+ " ";
+ scanner = XMLScanner.createScanner(dtd, true);
+ assertOffsetAndToken(0, TokenType.Content);
+ assertOffsetAndToken(25, TokenType.Content);
+ assertOffsetAndToken(26, TokenType.DTDStartElement);
+ assertOffsetAndToken(35, TokenType.Whitespace);
+ assertOffsetAndToken(36, TokenType.DTDEndTag);
+ assertOffsetAndToken(37, TokenType.EOS);
+ }
+
+ @Test
+ public void dtdUnrecognizedContent() {
+ String dtd = " aaa gf ";
+
+ scanner = XMLScanner.createScanner(dtd, true);
+
+ assertOffsetAndToken(0, TokenType.DTDStartElement);
+ assertOffsetAndToken(9, TokenType.DTDEndTag);
+ assertOffsetAndToken(10, TokenType.Content);
+ assertOffsetAndToken(22, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(31, TokenType.DTDEndTag);
+ assertOffsetAndToken(32, TokenType.EOS);
+ }
+
public void assertOffsetAndToken(int tokenOffset, TokenType tokenType) {
TokenType token = scanner.scan();
// System.err.println("assertOffsetAndToken(" + scanner.getTokenOffset() + ", TokenType." + scanner.getTokenType() + ");");
diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForInternalDTDTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForInternalDTDTest.java
index 242bf93623..801a22679e 100644
--- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForInternalDTDTest.java
+++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/dom/parser/XMLScannerForInternalDTDTest.java
@@ -34,21 +34,21 @@ public void testDocumentTypeInternalOnly() {
assertOffsetAndToken(10, TokenType.DTDDoctypeName);
assertOffsetAndToken(14, TokenType.Whitespace);
assertOffsetAndToken(15, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(16, TokenType.Whitespace);
+ assertOffsetAndToken(16, TokenType.Content);
assertOffsetAndToken(19, TokenType.DTDStartEntity);
assertOffsetAndToken(27, TokenType.Whitespace);
assertOffsetAndToken(28, TokenType.DTDEntityName);
assertOffsetAndToken(32, TokenType.Whitespace);
assertOffsetAndToken(33, TokenType.DTDEntityValue);
assertOffsetAndToken(41, TokenType.DTDEndTag);
- assertOffsetAndToken(42, TokenType.Whitespace);
+ assertOffsetAndToken(42, TokenType.Content);
assertOffsetAndToken(46, TokenType.DTDStartEntity);
assertOffsetAndToken(54, TokenType.Whitespace);
assertOffsetAndToken(55, TokenType.DTDEntityName);
assertOffsetAndToken(61, TokenType.Whitespace);
assertOffsetAndToken(62, TokenType.DTDEntityValue);
assertOffsetAndToken(84, TokenType.DTDEndTag);
- assertOffsetAndToken(85, TokenType.Whitespace);
+ assertOffsetAndToken(85, TokenType.Content);
assertOffsetAndToken(86, TokenType.DTDEndInternalSubset);
assertOffsetAndToken(87, TokenType.DTDEndDoctypeTag);
@@ -76,14 +76,14 @@ public void testDocumentTypePublicAndInternal() {
assertOffsetAndToken(67, TokenType.DTDDoctypeSystemId);
assertOffsetAndToken(124, TokenType.Whitespace);
assertOffsetAndToken(127, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(128, TokenType.Whitespace);
+ assertOffsetAndToken(128, TokenType.Content);
assertOffsetAndToken(133, TokenType.DTDStartEntity);
assertOffsetAndToken(141, TokenType.Whitespace);
assertOffsetAndToken(142, TokenType.DTDEntityName);
assertOffsetAndToken(146, TokenType.Whitespace);
assertOffsetAndToken(147, TokenType.DTDEntityValue);
assertOffsetAndToken(155, TokenType.DTDEndTag);
- assertOffsetAndToken(156, TokenType.Whitespace);
+ assertOffsetAndToken(156, TokenType.Content);
assertOffsetAndToken(160, TokenType.DTDEndInternalSubset);
assertOffsetAndToken(161, TokenType.Whitespace);
assertOffsetAndToken(162, TokenType.DTDEndDoctypeTag);
@@ -109,15 +109,16 @@ public void testDocumentTypeSystemAndInternal() {
assertOffsetAndToken(24, TokenType.DTDDoctypeSystemId);
assertOffsetAndToken(81, TokenType.Whitespace);
assertOffsetAndToken(84, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(85, TokenType.Whitespace);
- assertOffsetAndToken(90, TokenType.DTDStartElementDecl);
+ assertOffsetAndToken(85, TokenType.Content);
+ assertOffsetAndToken(90, TokenType.DTDStartElement);
assertOffsetAndToken(99, TokenType.Whitespace);
assertOffsetAndToken(100, TokenType.DTDElementDeclName);
assertOffsetAndToken(104, TokenType.Whitespace);
assertOffsetAndToken(105, TokenType.DTDStartElementContent);
- assertOffsetAndToken(106, TokenType.DTDEndElementContent);
+ assertOffsetAndToken(106, TokenType.DTDElementContent);
+ assertOffsetAndToken(107, TokenType.DTDEndElementContent);
assertOffsetAndToken(108, TokenType.DTDEndTag);
- assertOffsetAndToken(109, TokenType.Whitespace);
+ assertOffsetAndToken(109, TokenType.Content);
assertOffsetAndToken(113, TokenType.DTDEndInternalSubset);
assertOffsetAndToken(114, TokenType.Whitespace);
assertOffsetAndToken(115, TokenType.DTDEndDoctypeTag);
@@ -143,18 +144,18 @@ public void testDocumentTypeSystemAndInternalAttlist() {
assertOffsetAndToken(24, TokenType.DTDDoctypeSystemId);
assertOffsetAndToken(81, TokenType.Whitespace);
assertOffsetAndToken(84, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(85, TokenType.Whitespace);
- assertOffsetAndToken(90, TokenType.DTDStartAttlistDecl);
+ assertOffsetAndToken(85, TokenType.Content);
+ assertOffsetAndToken(90, TokenType.DTDStartAttlist);
assertOffsetAndToken(99, TokenType.Whitespace);
assertOffsetAndToken(100, TokenType.DTDAttlistElementName);
assertOffsetAndToken(107, TokenType.Whitespace);
assertOffsetAndToken(108, TokenType.DTDAttlistAttributeName);
assertOffsetAndToken(112, TokenType.Whitespace);
- assertOffsetAndToken(113, TokenType.DTDAttlistType);
+ assertOffsetAndToken(113, TokenType.DTDAttlistAttributeType);
assertOffsetAndToken(118, TokenType.Whitespace);
assertOffsetAndToken(119, TokenType.DTDAttlistAttributeValue);
assertOffsetAndToken(127, TokenType.DTDEndTag);
- assertOffsetAndToken(128, TokenType.Whitespace);
+ assertOffsetAndToken(128, TokenType.Content);
assertOffsetAndToken(132, TokenType.DTDEndInternalSubset);
assertOffsetAndToken(133, TokenType.Whitespace);
assertOffsetAndToken(134, TokenType.DTDEndDoctypeTag);
@@ -180,18 +181,18 @@ public void testDocumentTypeSystemAndInternalAttlist2() {
assertOffsetAndToken(24, TokenType.DTDDoctypeSystemId);
assertOffsetAndToken(81, TokenType.Whitespace);
assertOffsetAndToken(84, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(85, TokenType.Whitespace);
- assertOffsetAndToken(90, TokenType.DTDStartAttlistDecl);
+ assertOffsetAndToken(85, TokenType.Content);
+ assertOffsetAndToken(90, TokenType.DTDStartAttlist);
assertOffsetAndToken(99, TokenType.Whitespace);
assertOffsetAndToken(100, TokenType.DTDAttlistElementName);
assertOffsetAndToken(107, TokenType.Whitespace);
assertOffsetAndToken(108, TokenType.DTDAttlistAttributeName);
assertOffsetAndToken(112, TokenType.Whitespace);
- assertOffsetAndToken(113, TokenType.DTDAttlistType);
+ assertOffsetAndToken(113, TokenType.DTDAttlistAttributeType);
assertOffsetAndToken(127, TokenType.Whitespace);
assertOffsetAndToken(128, TokenType.DTDAttlistAttributeValue);
assertOffsetAndToken(135, TokenType.DTDEndTag);
- assertOffsetAndToken(136, TokenType.Whitespace);
+ assertOffsetAndToken(136, TokenType.Content);
assertOffsetAndToken(140, TokenType.DTDEndInternalSubset);
assertOffsetAndToken(141, TokenType.Whitespace);
assertOffsetAndToken(142, TokenType.DTDEndDoctypeTag);
@@ -216,7 +217,7 @@ public void testDocumentTypeSystemAndEmptyInternalDTD() {
assertOffsetAndToken(24, TokenType.DTDDoctypeSystemId);
assertOffsetAndToken(81, TokenType.Whitespace);
assertOffsetAndToken(84, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(85, TokenType.Whitespace);
+ assertOffsetAndToken(85, TokenType.Content);
assertOffsetAndToken(88, TokenType.DTDEndInternalSubset);
assertOffsetAndToken(89, TokenType.Whitespace);
assertOffsetAndToken(90, TokenType.DTDEndDoctypeTag);
@@ -251,8 +252,8 @@ public void oneElementDeclNotClosed () {
assertOffsetAndToken(10, TokenType.DTDDoctypeName);
assertOffsetAndToken(13, TokenType.Whitespace);
assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(15, TokenType.Whitespace);
- assertOffsetAndToken(17, TokenType.DTDStartElementDecl);
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(17, TokenType.DTDStartElement);
assertOffsetAndToken(26, TokenType.Whitespace);
assertOffsetAndToken(27, TokenType.DTDElementDeclName);
assertOffsetAndToken(28, TokenType.DTDEndInternalSubset);
@@ -277,12 +278,12 @@ public void startWithElementDeclNotClosed () {
assertOffsetAndToken(10, TokenType.DTDDoctypeName);
assertOffsetAndToken(13, TokenType.Whitespace);
assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
- assertOffsetAndToken(15, TokenType.Whitespace);
- assertOffsetAndToken(17, TokenType.DTDStartElementDecl);
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(17, TokenType.DTDStartElement);
assertOffsetAndToken(26, TokenType.Whitespace);
assertOffsetAndToken(27, TokenType.DTDElementDeclName);
assertOffsetAndToken(28, TokenType.Whitespace);
- assertOffsetAndToken(30, TokenType.DTDStartElementDecl);
+ assertOffsetAndToken(30, TokenType.DTDStartElement);
assertOffsetAndToken(39, TokenType.Whitespace);
assertOffsetAndToken(40, TokenType.DTDElementDeclName);
assertOffsetAndToken(41, TokenType.DTDEndInternalSubset);
@@ -295,6 +296,139 @@ public void startWithElementDeclNotClosed () {
assertOffsetAndToken(55, TokenType.EOS);
}
+ @Test
+ public void startWithNotationDeclNotClosed () {
+ String xml =
+ "";
+ scanner = XMLScanner.createScanner(xml);
+ assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDDoctypeName);
+ assertOffsetAndToken(13, TokenType.Whitespace);
+ assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(19, TokenType.DTDStartNotation);
+ assertOffsetAndToken(29, TokenType.Whitespace);
+ assertOffsetAndToken(30, TokenType.DTDNotationName);
+ assertOffsetAndToken(31, TokenType.Whitespace);
+ assertOffsetAndToken(33, TokenType.DTDEndInternalSubset);
+ assertOffsetAndToken(34, TokenType.Whitespace);
+ assertOffsetAndToken(36, TokenType.StartTagOpen);
+ assertOffsetAndToken(37, TokenType.StartTag);
+ assertOffsetAndToken(40, TokenType.Whitespace);
+ assertOffsetAndToken(41, TokenType.StartTagSelfClose);
+ assertOffsetAndToken(43, TokenType.EOS);
+ }
+
+ @Test
+ public void startWithNotationDeclNotClosedWithContent () {
+ String xml =
+ "";
+ scanner = XMLScanner.createScanner(xml);
+ assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDDoctypeName);
+ assertOffsetAndToken(13, TokenType.Whitespace);
+ assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(19, TokenType.DTDStartNotation);
+ assertOffsetAndToken(29, TokenType.Whitespace);
+ assertOffsetAndToken(30, TokenType.DTDNotationName);
+ assertOffsetAndToken(31, TokenType.Whitespace);
+ assertOffsetAndToken(33, TokenType.DTDEndInternalSubset);
+ assertOffsetAndToken(34, TokenType.Whitespace);
+ assertOffsetAndToken(35, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(44, TokenType.StartTagOpen);
+ assertOffsetAndToken(45, TokenType.StartTag);
+ assertOffsetAndToken(48, TokenType.Whitespace);
+ assertOffsetAndToken(49, TokenType.StartTagSelfClose);
+ assertOffsetAndToken(51, TokenType.EOS);
+ }
+
+ @Test
+ public void startWithEntityDeclNotClosedWithContent () {
+ String xml =
+ "";
+ scanner = XMLScanner.createScanner(xml);
+ assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDDoctypeName);
+ assertOffsetAndToken(13, TokenType.Whitespace);
+ assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(19, TokenType.DTDStartEntity);
+ assertOffsetAndToken(27, TokenType.Whitespace);
+ assertOffsetAndToken(28, TokenType.DTDEntityName);
+ assertOffsetAndToken(29, TokenType.Whitespace);
+ assertOffsetAndToken(31, TokenType.DTDEndInternalSubset);
+ assertOffsetAndToken(32, TokenType.Whitespace);
+ assertOffsetAndToken(33, TokenType.DTDUnrecognizedParameters);
+ assertOffsetAndToken(42, TokenType.StartTagOpen);
+ assertOffsetAndToken(43, TokenType.StartTag);
+ assertOffsetAndToken(46, TokenType.Whitespace);
+ assertOffsetAndToken(47, TokenType.StartTagSelfClose);
+ assertOffsetAndToken(49, TokenType.EOS);
+ }
+
+ @Test
+ public void startWithAttlistDeclNotClosed() {
+ String xml =
+ "";
+ scanner = XMLScanner.createScanner(xml);
+ assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDDoctypeName);
+ assertOffsetAndToken(13, TokenType.Whitespace);
+ assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
+
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(19, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(28, TokenType.Whitespace);
+
+ assertOffsetAndToken(31, TokenType.DTDEndInternalSubset);
+ assertOffsetAndToken(32, TokenType.Whitespace);
+
+ assertOffsetAndToken(34, TokenType.StartTagOpen);
+ assertOffsetAndToken(35, TokenType.StartTag);
+ assertOffsetAndToken(38, TokenType.Whitespace);
+ assertOffsetAndToken(39, TokenType.StartTagSelfClose);
+ assertOffsetAndToken(41, TokenType.EOS);
+ }
+
+ @Test
+ public void startWithAttlistDeclNotClosedAndMissingEndInternalSubset() {
+ String xml =
+ "";
+ scanner = XMLScanner.createScanner(xml);
+ assertOffsetAndToken(0, TokenType.DTDStartDoctypeTag);
+ assertOffsetAndToken(9, TokenType.Whitespace);
+ assertOffsetAndToken(10, TokenType.DTDDoctypeName);
+ assertOffsetAndToken(13, TokenType.Whitespace);
+ assertOffsetAndToken(14, TokenType.DTDStartInternalSubset);
+
+ assertOffsetAndToken(15, TokenType.Content);
+ assertOffsetAndToken(19, TokenType.DTDStartAttlist);
+ assertOffsetAndToken(28, TokenType.Whitespace);
+
+ assertOffsetAndToken(33, TokenType.Content);
+ assertOffsetAndToken(40, TokenType.EOS);
+ }
+
public void assertOffsetAndToken(int tokenOffset, TokenType tokenType) {
TokenType token = scanner.scan();
// System.err.println("assertOffsetAndToken(" + scanner.getTokenOffset() + ", TokenType." + scanner.getTokenType() + ");");
@@ -309,3 +443,4 @@ public void assertOffsetAndToken(int tokenOffset, TokenType tokenType, String to
assertEquals(tokenText, scanner.getTokenText());
}
}
+
diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLDocumentSymbolsTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLDocumentSymbolsTest.java
index cc8aa89d55..a337de5528 100644
--- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLDocumentSymbolsTest.java
+++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/services/XMLDocumentSymbolsTest.java
@@ -30,7 +30,8 @@ public void externalDTD() {
@Test
public void internalDTD() {
- String xml = "\r\n" + //
+ String xml =
+ "\r\n" + //
"\r\n" + //
" \r\n" + //