Skip to content

Commit

Permalink
fix: Interaction between XInclude and <?xml-model> PI
Browse files Browse the repository at this point in the history
Fixes redhat-developer/vscode-xml#1021

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Aug 23, 2024
1 parent 1063ef0 commit 52d4325
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public class XMLModelHandler implements XMLComponent, XMLDocumentFilter {

private XMLReader xmlReader;

private boolean beforeDocumentElement;

public XMLModelHandler() {
}

Expand Down Expand Up @@ -122,7 +124,7 @@ public boolean getFeature(String featureId) throws XMLConfigurationException {

@Override
public void processingInstruction(String target, XMLString data, Augmentations augs) throws XNIException {
if (XMLModelConstants.XML_MODEL_PI.equals(target)) {
if (beforeDocumentElement && XMLModelConstants.XML_MODEL_PI.equals(target)) {
XMLModelDeclaration model = XMLModelDeclaration.parse(data);
XMLModelValidator validator = createValidator(model);
if (validator != null) {
Expand Down Expand Up @@ -159,6 +161,7 @@ private XMLModelValidator createValidator(XMLModelDeclaration modelDeclaration)
@Override
public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext,
Augmentations augs) throws XNIException {
this.beforeDocumentElement = true;
this.locator = locator;
if (xmlModelValidators != null) {
for (XMLModelValidator validator : xmlModelValidators) {
Expand Down Expand Up @@ -213,6 +216,7 @@ public void comment(XMLString text, Augmentations augs) throws XNIException {

@Override
public void startElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException {
this.beforeDocumentElement = false;
if (xmlModelValidators != null) {
for (XMLModelValidator validator : xmlModelValidators) {
validator.setLocator(locator);
Expand All @@ -230,6 +234,7 @@ public void startElement(QName element, XMLAttributes attributes, Augmentations

@Override
public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException {
this.beforeDocumentElement = false;
if (xmlModelValidators != null) {
for (XMLModelValidator validator : xmlModelValidators) {
validator.emptyElement(element, attributes, augs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
import static org.eclipse.lemminx.XMLAssert.d;
import static org.eclipse.lemminx.XMLAssert.testDiagnosticsFor;

import java.io.File;

import org.eclipse.lemminx.AbstractCacheBasedTest;
import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationRootSettings;
import org.eclipse.lemminx.extensions.relaxng.xml.validator.RelaxNGErrorCode;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -171,4 +175,29 @@ public void not_allowed_yet() throws Exception {
d(2, 2, 10, RelaxNGErrorCode.element_not_allowed_yet));
}

@Test
public void xinclude() throws Exception {
ContentModelSettings settings = new ContentModelSettings();
XMLValidationRootSettings validation = new XMLValidationRootSettings();
validation.getXInclude().setEnabled(true);
settings.setValidation(validation);
String fileURI = new File("src/test/resources/relaxng/xinclude-chapter/document.xml").toURI().toString();

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //
"<?xml-model href=\"document.rnc\"?>\r\n" + //
"<document xmlns:xi=\"http://www.w3.org/2001/XInclude\">\r\n" + //
" <xi:include href=\"chapter1.xml\"/>\r\n" + //
" <xi:include href=\"chapter2.xml\"/>\r\n" + //
"</document>";
testDiagnosticsFor(xml, null, null, fileURI, true, settings);

xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //
"<?xml-model href=\"document.rnc\"?>\r\n" + //
"<document xmlns:xi=\"http://www.w3.org/2001/XInclude\">\r\n" + //
" <xi:include href=\"chapter1.xml\"/>\r\n" + //
" <xi:include href=\"book.xml\"/>\r\n" + //
"</document>";
testDiagnosticsFor(xml, null, null, fileURI, true, settings, //
d(2, 1, 9, null)); // "There is '1' error in 'book.xml'."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<book></book>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include "common.rnc"

start = chapter
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="chapter.rnc"?>
<chapter>
<title>Chapter</title>
</chapter>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="chapter.rnc"?>
<chapter>
<title>Chapter</title>
</chapter>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace xml = "http://www.w3.org/XML/1998/namespace"

base = attribute xml:base { text }

chapter = element chapter {
element title { text }
& base?
}

document = element document {
chapter+
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include "common.rnc"

start = document
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="document.rnc"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="chapter1.xml"/>
<xi:include href="chapter2.xml"/>
</document>

0 comments on commit 52d4325

Please sign in to comment.