diff --git a/src/main/java/com/siemens/ct/exi/main/api/stream/StAXEncoder.java b/src/main/java/com/siemens/ct/exi/main/api/stream/StAXEncoder.java
index 7db698dc..40ffc5e0 100644
--- a/src/main/java/com/siemens/ct/exi/main/api/stream/StAXEncoder.java
+++ b/src/main/java/com/siemens/ct/exi/main/api/stream/StAXEncoder.java
@@ -85,6 +85,9 @@ public class StAXEncoder implements XMLStreamWriter {
protected final boolean preserveComment;
protected final boolean preservePI;
+ // indicate whether an "empty" element was started
+ protected boolean emptyElement;
+
// AT or NS Events pending
protected boolean pendingATs;
@@ -115,6 +118,7 @@ public void setOutputStream(OutputStream os) throws EXIException,
}
protected void init() {
+ emptyElement = false;
pendingATs = false;
exiAttributes.clear();
nsContext.reset();
@@ -289,8 +293,12 @@ protected void checkPendingATEvents() throws EXIException, IOException {
// encode NS decls and attributes
encoder.encodeAttributeList(exiAttributes);
exiAttributes.clear();
-
pendingATs = false;
+
+ if (emptyElement) {
+ encoder.encodeEndElement();
+ emptyElement = false;
+ }
}
}
@@ -618,7 +626,9 @@ public void writeEmptyElement(String namespaceURI, String localName)
public void writeEmptyElement(String prefix, String localName,
String namespaceURI) throws XMLStreamException {
this.writeStartElement(prefix, localName, namespaceURI);
- this.writeEndElement();
+ // Note: we cannot close the element immediately since attributes might follow
+ // this.writeEndElement();
+ emptyElement = true;
}
public void writeStartDocument(String version) throws XMLStreamException {
diff --git a/src/test/java/com/siemens/ct/exi/main/ParallelTest.java b/src/test/java/com/siemens/ct/exi/main/ParallelTest.java
index b2cbaf8f..c420ef34 100644
--- a/src/test/java/com/siemens/ct/exi/main/ParallelTest.java
+++ b/src/test/java/com/siemens/ct/exi/main/ParallelTest.java
@@ -48,6 +48,7 @@
import com.siemens.ct.exi.main.data.AbstractTestCase;
import com.siemens.ct.exi.main.data.TestXSDResolver;
+@Ignore("https://github.com/EXIficient/exificient/issues/45")
public class ParallelTest extends AbstractTestCase {
static final int ENCODE_THREADS = 4; // 8
diff --git a/src/test/java/com/siemens/ct/exi/main/api/stream/StAXCoderTestCase.java b/src/test/java/com/siemens/ct/exi/main/api/stream/StAXCoderTestCase.java
index 0a469561..fcda8bd7 100644
--- a/src/test/java/com/siemens/ct/exi/main/api/stream/StAXCoderTestCase.java
+++ b/src/test/java/com/siemens/ct/exi/main/api/stream/StAXCoderTestCase.java
@@ -527,6 +527,96 @@ public void testIssue18_simpifiedNoPrefix() throws AssertionFailedError,
}
}
+
+ // https://github.com/EXIficient/exificient/issues/43
+ public void testEmptyElement() throws Exception {
+ //
+ //
+ // myTitle
+ //
+
+ EXIFactory ef = DefaultEXIFactory.newInstance();
+
+ // Version A: empty Element with SE ... EE
+ {
+ StAXEncoder staxEncoder = new StAXEncoder(ef);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ staxEncoder.setOutputStream(baos);
+
+ staxEncoder.writeStartDocument();
+ staxEncoder.writeStartElement("head");
+ staxEncoder.writeStartElement("link");
+ staxEncoder.writeAttribute("rel", "stylesheet");
+ staxEncoder.writeAttribute("href", "css/xmlwriter01.css");
+ staxEncoder.writeEndElement();
+ staxEncoder.writeStartElement("title");
+ staxEncoder.writeCharacters("myTitle");
+ staxEncoder.writeEndElement();
+ staxEncoder.writeEndElement();
+ staxEncoder.writeEndDocument();
+
+ // decode
+ StAXDecoder staxDecoder = new StAXDecoder(ef);
+ staxDecoder.setInputStream(new ByteArrayInputStream(baos.toByteArray()));
+ _checkDecodeEmptyElement(staxDecoder);
+ }
+
+
+ // Version B: using writeEmptyElement
+ {
+ StAXEncoder staxEncoder = new StAXEncoder(ef);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ staxEncoder.setOutputStream(baos);
+
+ staxEncoder.writeStartDocument();
+ staxEncoder.writeStartElement("head");
+ staxEncoder.writeEmptyElement("link");
+ staxEncoder.writeAttribute("rel", "stylesheet");
+ staxEncoder.writeAttribute("href", "css/xmlwriter01.css");
+ staxEncoder.writeStartElement("title");
+ staxEncoder.writeCharacters("myTitle");
+ staxEncoder.writeEndElement();
+ staxEncoder.writeEndElement();
+ staxEncoder.writeEndDocument();
+
+ // decode
+ StAXDecoder staxDecoder = new StAXDecoder(ef);
+ staxDecoder.setInputStream(new ByteArrayInputStream(baos.toByteArray()));
+ _checkDecodeEmptyElement(staxDecoder);
+ }
+ }
+
+ void _checkDecodeEmptyElement(StAXDecoder staxDecoder) throws Exception {
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.START_ELEMENT, staxDecoder.next());
+ assertEquals("head", staxDecoder.getName().getLocalPart());
+
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.START_ELEMENT, staxDecoder.next());
+ assertEquals("link", staxDecoder.getName().getLocalPart());
+
+ assertEquals(2, staxDecoder.getAttributeCount());
+ assertEquals("rel", staxDecoder.getAttributeName(0).getLocalPart());
+ assertEquals("stylesheet", staxDecoder.getAttributeValue(0));
+
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.END_ELEMENT, staxDecoder.next());
+
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.START_ELEMENT, staxDecoder.next());
+ assertEquals("title", staxDecoder.getName().getLocalPart());
+
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.CHARACTERS, staxDecoder.next());
+ assertEquals("myTitle", new String(staxDecoder.getTextCharacters()));
+
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.END_ELEMENT, staxDecoder.next());
+
+ assertTrue(staxDecoder.hasNext());
+ assertEquals(XMLStreamConstants.END_ELEMENT, staxDecoder.next());
+ }
+
public static void main(String[] args) throws Exception {
StAXCoderTestCase st = new StAXCoderTestCase("StAX");