[DEV] refacto separate serializer, parser and model is OK ==> sax reader is OK not the sax generator (API not open)
This commit is contained in:
parent
d16f4c95e3
commit
f610c366ba
@ -6,6 +6,10 @@
|
||||
|
||||
open module org.atriasoft.exml {
|
||||
exports org.atriasoft.exml;
|
||||
exports org.atriasoft.exml.model;
|
||||
exports org.atriasoft.exml.exception;
|
||||
exports org.atriasoft.exml.builder;
|
||||
exports org.atriasoft.exml.parser;
|
||||
|
||||
requires transitive org.atriasoft.etk;
|
||||
requires transitive io.scenarium.logger;
|
||||
|
@ -9,8 +9,13 @@ package org.atriasoft.exml;
|
||||
import org.atriasoft.exml.builder.Builder;
|
||||
import org.atriasoft.exml.builder.BuilderGeneric;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
import org.atriasoft.exml.model.XmlElement;
|
||||
import org.atriasoft.exml.model.XmlNode;
|
||||
import org.atriasoft.exml.parser.ParseXml;
|
||||
import org.atriasoft.exml.parser.ParsingProperty;
|
||||
import org.atriasoft.exml.serializer.SerializerXml;
|
||||
|
||||
public class Exml {
|
||||
/**
|
||||
@ -28,35 +33,21 @@ public class Exml {
|
||||
* @return false : An error occured
|
||||
* @return true : Parsing is OK
|
||||
*/
|
||||
public static boolean generate(final StringBuilder _data) {
|
||||
//return iGenerate(_data, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
/*
|
||||
for (int iii = 0; iii < this.listSub.size(); iii++) {
|
||||
if (this.listSub.get(iii) != null) {
|
||||
this.listSub.get(iii).iGenerate(_data, _indent);
|
||||
}
|
||||
public static void generate(final XmlNode root, final StringBuilder _data) {
|
||||
if (root.isElement() == false || ((XmlElement) root).getValue().isEmpty() == false) {
|
||||
SerializerXml.serialize(root, _data, 0);
|
||||
} else {
|
||||
SerializerXml.serializeRoot((XmlElement) root, _data);
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
//return iGenerate(_data, 0);
|
||||
}
|
||||
|
||||
public static XmlNode parse(final String data) {
|
||||
|
||||
public static XmlElement parse(final String data) throws ExmlBuilderException, ExmlParserErrorMulti {
|
||||
final Builder builder = new BuilderGeneric();
|
||||
final ParseXml parser = new ParseXml(builder);
|
||||
|
||||
Object out = null;
|
||||
try {
|
||||
out = parser.parse(data);
|
||||
} catch (final ExmlBuilderException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return (XmlNode) out;
|
||||
final ParsingProperty property = new ParsingProperty();
|
||||
property.setDisplayError(true);
|
||||
return (XmlElement) parser.parse(data, property);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,25 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
|
||||
public class TextCDATA extends XmlText {
|
||||
public TextCDATA() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TextCDATA(final String data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
_data.append("<![CDATA[");
|
||||
_data.append(this.value);
|
||||
_data.append("]]>");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,12 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml.builder;
|
||||
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
|
||||
/**
|
||||
* @author heero
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author heero
|
||||
*
|
||||
*/
|
||||
public interface Builder {
|
||||
|
||||
/**
|
||||
|
@ -1,12 +1,17 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml.builder;
|
||||
|
||||
import org.atriasoft.exml.XmlAttribute;
|
||||
import org.atriasoft.exml.XmlAttributeList;
|
||||
import org.atriasoft.exml.XmlComment;
|
||||
import org.atriasoft.exml.XmlDeclaration;
|
||||
import org.atriasoft.exml.XmlElement;
|
||||
import org.atriasoft.exml.XmlText;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.model.XmlAttribute;
|
||||
import org.atriasoft.exml.model.XmlAttributeList;
|
||||
import org.atriasoft.exml.model.XmlComment;
|
||||
import org.atriasoft.exml.model.XmlDeclaration;
|
||||
import org.atriasoft.exml.model.XmlElement;
|
||||
import org.atriasoft.exml.model.XmlText;
|
||||
|
||||
public class BuilderGeneric implements Builder {
|
||||
|
||||
@ -15,6 +20,7 @@ public class BuilderGeneric implements Builder {
|
||||
if (element instanceof XmlElement) {
|
||||
final XmlElement elem = (XmlElement) element;
|
||||
elem.append(new XmlComment(comment));
|
||||
return;
|
||||
}
|
||||
throw new ExmlBuilderException("can not add Comment on something else than Element");
|
||||
}
|
||||
|
25
src/org/atriasoft/exml/exception/ExmlParserError.java
Normal file
25
src/org/atriasoft/exml/exception/ExmlParserError.java
Normal file
@ -0,0 +1,25 @@
|
||||
package org.atriasoft.exml.exception;
|
||||
|
||||
import org.atriasoft.exml.parser.FilePos;
|
||||
|
||||
public class ExmlParserError extends ExmlBuilderException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String dataLine; //!< Parse line error (copy);
|
||||
|
||||
private final FilePos filePos; //!< position of the error
|
||||
|
||||
public ExmlParserError(final String dataLine, final FilePos filePos, final String comment) {
|
||||
super(comment);
|
||||
this.dataLine = dataLine;
|
||||
this.filePos = filePos.clone();
|
||||
}
|
||||
|
||||
public String getDataLine() {
|
||||
return this.dataLine;
|
||||
}
|
||||
|
||||
public FilePos getFilePos() {
|
||||
return this.filePos;
|
||||
}
|
||||
|
||||
}
|
18
src/org/atriasoft/exml/exception/ExmlParserErrorMulti.java
Normal file
18
src/org/atriasoft/exml/exception/ExmlParserErrorMulti.java
Normal file
@ -0,0 +1,18 @@
|
||||
package org.atriasoft.exml.exception;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ExmlParserErrorMulti extends ExmlBuilderException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final List<ExmlParserError> errors; // list of errors
|
||||
|
||||
public ExmlParserErrorMulti(final String message, final List<ExmlParserError> errors) {
|
||||
super(message);
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public List<ExmlParserError> getErrors() {
|
||||
return this.errors;
|
||||
}
|
||||
|
||||
}
|
@ -3,9 +3,9 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
import org.atriasoft.exml.internal.FilePos;
|
||||
import org.atriasoft.exml.parser.FilePos;
|
||||
|
||||
/**
|
||||
* Single attribute element
|
||||
@ -68,15 +68,6 @@ public class XmlAttribute {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
_data.append(" ");
|
||||
_data.append(this.name);
|
||||
_data.append("=\"");
|
||||
_data.append(this.value);
|
||||
_data.append("\"");
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* set the name of the attribute
|
||||
* @param[in] _name New name of the attribute
|
@ -3,9 +3,10 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
@ -108,7 +109,7 @@ public abstract class XmlAttributeList extends XmlNode {
|
||||
}
|
||||
|
||||
public List<XmlAttribute> getAttributes() {
|
||||
return this.listAttribute;
|
||||
return Collections.unmodifiableList(this.listAttribute);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,16 +123,6 @@ public abstract class XmlAttributeList extends XmlNode {
|
||||
return new Pair<String, String>(att.getName(), att.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
for (int iii = 0; iii < this.listAttribute.size(); iii++) {
|
||||
if (this.listAttribute.get(iii) != null) {
|
||||
this.listAttribute.get(iii).iGenerate(_data, _indent);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an attribute form the list
|
||||
* @param[in] _name Name of the attribute
|
@ -3,9 +3,7 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.internal.Tools;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
/**
|
||||
* Comment node: lt;!-- ... --gt;
|
||||
@ -38,13 +36,4 @@ public class XmlComment extends XmlNode {
|
||||
return XmlNodeType.COMMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
Tools.addIndent(_data, _indent);
|
||||
_data.append("<!--");
|
||||
_data.append(this.value);
|
||||
_data.append("-->\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
@ -3,10 +3,9 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
import org.atriasoft.exml.internal.Tools;
|
||||
|
||||
/**
|
||||
* Declaration node: lt;?XXXXXX ... gt;
|
||||
@ -57,16 +56,5 @@ public class XmlDeclaration extends XmlAttributeList {
|
||||
@Override
|
||||
public XmlNodeType getType() {
|
||||
return XmlNodeType.DECLARATION;
|
||||
};
|
||||
|
||||
@Override
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
Tools.addIndent(_data, _indent);
|
||||
_data.append("<?");
|
||||
_data.append(this.value);
|
||||
super.iGenerate(_data, _indent);
|
||||
_data.append("?>\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -3,15 +3,16 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
import org.atriasoft.exml.internal.Tools;
|
||||
import org.atriasoft.exml.serializer.SerializerXml;
|
||||
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
@ -147,12 +148,12 @@ public class XmlElement extends XmlAttributeList {
|
||||
* @return List of current nodes.
|
||||
*/
|
||||
public List<XmlNode> getNodes() {
|
||||
return this.listSub;
|
||||
return Collections.unmodifiableList(this.listSub);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the internal data of the element (if the element has some sub node they are converted in xml string == > like this it is not needed to use <![CDATA[...]]>
|
||||
* @return the curent data string. if Only one text node, then we get the parssed data (no amp; ...) if more than one node, then we transform ,",',<,> in xml normal text...
|
||||
* Get the internal data of the element (if the element has some sub node they are converted in xml string == > like this it is not needed to use <![CDATA[...]]>
|
||||
* @return the current data string. if Only one text node, then we get the parsed data (no amp; ...) if more than one node, then we transform ,",',<,> in xml normal text...
|
||||
*/
|
||||
public String getText() {
|
||||
final StringBuilder res = new StringBuilder();
|
||||
@ -160,12 +161,12 @@ public class XmlElement extends XmlAttributeList {
|
||||
if (this.listSub.get(0).getType() == XmlNodeType.TEXT) {
|
||||
res.append(this.listSub.get(0).getValue());
|
||||
} else {
|
||||
this.listSub.get(0).iGenerate(res, 0);
|
||||
SerializerXml.serialize(this.listSub.get(0), res, 0);
|
||||
}
|
||||
} else {
|
||||
for (int iii = 0; iii < this.listSub.size(); iii++) {
|
||||
if (this.listSub.get(iii) != null) {
|
||||
this.listSub.get(iii).iGenerate(res, 0);
|
||||
SerializerXml.serialize(this.listSub.get(iii), res, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,36 +191,6 @@ public class XmlElement extends XmlAttributeList {
|
||||
return this.listSub.get(_id).getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
Tools.addIndent(_data, _indent);
|
||||
_data.append("<");
|
||||
_data.append(this.value);
|
||||
super.iGenerate(_data, _indent);
|
||||
|
||||
if (this.listSub.size() > 0) {
|
||||
if (this.listSub.size() == 1 && this.listSub.get(0) != null && this.listSub.get(0).getType() == XmlNodeType.TEXT && ((XmlText) this.listSub.get(0)).countLines() == 1) {
|
||||
_data.append(">");
|
||||
this.listSub.get(0).iGenerate(_data, 0);
|
||||
Log.verbose(" generate : '" + _data + "'");
|
||||
} else {
|
||||
_data.append(">\n");
|
||||
for (int iii = 0; iii < this.listSub.size(); iii++) {
|
||||
if (this.listSub.get(iii) != null) {
|
||||
this.listSub.get(iii).iGenerate(_data, _indent + 1);
|
||||
}
|
||||
}
|
||||
Tools.addIndent(_data, _indent);
|
||||
}
|
||||
_data.append("</");
|
||||
_data.append(this.value);
|
||||
_data.append(">\n");
|
||||
} else {
|
||||
_data.append("/>\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all element with this name
|
||||
* @param[in] _nodeName Name of nodes to remove.
|
@ -3,63 +3,48 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.internal.FilePos;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
/**
|
||||
* Basic main object of all xml elements.
|
||||
*/
|
||||
public abstract class XmlNode {
|
||||
|
||||
protected FilePos pos; //!< position in the read file (null if the file is not parsed)
|
||||
protected String value; //!< value of the node (for element this is the name, for text it is the inside text ...);
|
||||
/// Value of the node (for element this is the name, for text it is the inside text ...);
|
||||
protected String value = "";
|
||||
|
||||
/**
|
||||
* basic element of a xml structure
|
||||
*/
|
||||
public XmlNode() {
|
||||
this.pos = null;
|
||||
}
|
||||
public XmlNode() {}
|
||||
|
||||
/**
|
||||
* basic element of a xml structure
|
||||
* Basic element of a xml structure
|
||||
* @param[in] _value value of the node
|
||||
*/
|
||||
public XmlNode(final String _value) {
|
||||
this.pos = null;
|
||||
this.value = _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the Node
|
||||
* Clear the Node
|
||||
*/
|
||||
public void clear() {
|
||||
this.value = "";
|
||||
this.pos = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XmlNode clone() throws CloneNotSupportedException {
|
||||
throw new CloneNotSupportedException("Can not clone an abstract class ...");
|
||||
throw new CloneNotSupportedException("Can not clone an abs ctract class ...");
|
||||
}
|
||||
|
||||
/**
|
||||
* get the current position where the element is in the file
|
||||
* @return The file position reference
|
||||
*/
|
||||
public FilePos getPos() {
|
||||
return this.pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the node type.
|
||||
* Get the node type.
|
||||
* @return the type of the Node.
|
||||
*/
|
||||
public abstract XmlNodeType getType();
|
||||
|
||||
/**
|
||||
* get the current element Value.
|
||||
* Get the current element Value.
|
||||
* @return the reference of the string value.
|
||||
*/
|
||||
public String getValue() {
|
||||
@ -67,26 +52,7 @@ public abstract class XmlNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a string with the tree of the xml
|
||||
* @param[in,out] _data string where to add the elements
|
||||
* @param[in] _indent current indentation of the file
|
||||
* @return false if an error occured.
|
||||
*/
|
||||
protected abstract boolean iGenerate(final StringBuilder _data, final int _indent);
|
||||
|
||||
/**
|
||||
* parse the Current node [pure VIRUAL]
|
||||
* @param[in] _data data string to parse.
|
||||
* @param[in,out] _pos position in the string to start parse, return the position end of parsing.
|
||||
* @param[in] _caseSensitive Request a parsion of element that is not case sensitive (all element is in low case)
|
||||
* @param[in,out] _filePos file parsing position (line x col x)
|
||||
* @param[in,out] _doc Base document reference
|
||||
* @return false if an error occured.
|
||||
*/
|
||||
//protected abstract boolean iParse(String _data, PositionParsing _pos, boolean _caseSensitive, FilePos _filePos, Document _doc);
|
||||
|
||||
/**
|
||||
* check if the node is a Comment
|
||||
* Check if the node is a Comment
|
||||
* @return true if the node is a Comment
|
||||
*/
|
||||
public final boolean isComment() {
|
||||
@ -101,14 +67,6 @@ public abstract class XmlNode {
|
||||
return this instanceof XmlDeclaration;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the node is a Document
|
||||
* @return true if the node is a Document
|
||||
*/
|
||||
public final boolean isDocument() {
|
||||
return this instanceof Document;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the node is a Element
|
||||
* @return true if the node is a Element
|
||||
@ -129,7 +87,6 @@ public abstract class XmlNode {
|
||||
* set the value of the node.
|
||||
* @param[in] _value New value of the node.
|
||||
*/
|
||||
|
||||
public final void setValue(final String _value) {
|
||||
this.value = _value;
|
||||
}
|
||||
@ -150,14 +107,6 @@ public abstract class XmlNode {
|
||||
return (XmlDeclaration) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the element in a Document if it is possible.
|
||||
* @return pointer on the class or null.
|
||||
*/
|
||||
public final Document toDocument() {
|
||||
return (Document) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the element in a Element if it is possible.
|
||||
* @return pointer on the class or null.
|
@ -3,13 +3,12 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
/**
|
||||
* Type of the XML elements.
|
||||
*/
|
||||
public enum XmlNodeType {
|
||||
DOCUMENT, //!< all the file main access
|
||||
DECLARATION, //!< <?xml ... ?>
|
||||
ELEMENT, //!< the <XXX> ... </XXX>
|
||||
COMMENT, //!< comment node : <!-- -->
|
@ -3,7 +3,7 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml;
|
||||
package org.atriasoft.exml.model;
|
||||
|
||||
/**
|
||||
* Text node interface (internal data between two Marker: <XXX> ALL here </XXX>
|
||||
@ -27,7 +27,7 @@ public class XmlText extends XmlNode {
|
||||
* count the number of line in the current text
|
||||
* @return The number of lines
|
||||
*/
|
||||
protected int countLines() {
|
||||
public int countLines() {
|
||||
int count = 1;
|
||||
for (int iii = 0; iii < this.value.length(); iii++) {
|
||||
if (this.value.charAt(iii) == '\n') {
|
||||
@ -40,12 +40,6 @@ public class XmlText extends XmlNode {
|
||||
@Override
|
||||
public XmlNodeType getType() {
|
||||
return XmlNodeType.TEXT;
|
||||
};
|
||||
|
||||
@Override
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
_data.append(replaceSpecialCharOut(this.value));
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
@ -3,7 +3,7 @@
|
||||
* @copyright 2021, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
package org.atriasoft.exml.internal;
|
||||
package org.atriasoft.exml.parser;
|
||||
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
@ -2,10 +2,9 @@ package org.atriasoft.exml.parser;
|
||||
|
||||
import org.atriasoft.exml.builder.Builder;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.internal.FilePos;
|
||||
import org.atriasoft.exml.exception.ExmlParserError;
|
||||
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
import org.atriasoft.exml.internal.PositionParsing;
|
||||
import org.atriasoft.exml.internal.Tools;
|
||||
|
||||
public class ParseXml {
|
||||
// global builder that is generate the final Tree
|
||||
@ -30,27 +29,32 @@ public class ParseXml {
|
||||
}
|
||||
}
|
||||
String name = _data.substring(_pos.value, lastElementName + 1);
|
||||
String value = "";
|
||||
if (parsingProperty.getCaseSensitive() == true) {
|
||||
if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) {
|
||||
name = name.toLowerCase();
|
||||
} else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) {
|
||||
name = name.toUpperCase();
|
||||
}
|
||||
|
||||
// TODO check if in the current list of attribute one is not currently set with this value...
|
||||
|
||||
String value = "";
|
||||
// count white space :
|
||||
final FilePos tmpPos = new FilePos();
|
||||
int white = Tools.countWhiteChar(_data, lastElementName + 1, tmpPos);
|
||||
_filePos.add(tmpPos);
|
||||
if (lastElementName + white + 1 >= _data.length()) {
|
||||
parsingProperty.createError(_data, lastElementName + white + 1, _filePos, " parse an xml end with an attribute parsing...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, lastElementName + white + 1), _filePos, " parse an xml end with an attribute parsing..."));
|
||||
return false;
|
||||
}
|
||||
if (_data.charAt(lastElementName + white + 1) != '=') {
|
||||
parsingProperty.createError(_data, lastElementName + white + 1, _filePos, " error attribute parsing == > missing '=' ...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, lastElementName + white + 1), _filePos, " error attribute parsing == > missing '=' ..."));
|
||||
return false;
|
||||
}
|
||||
white += Tools.countWhiteChar(_data, lastElementName + white + 2, tmpPos);
|
||||
_filePos.add(tmpPos);
|
||||
|
||||
if (lastElementName + white + 2 >= _data.length()) {
|
||||
parsingProperty.createError(_data, lastElementName + white + 2, _filePos, " parse an xml end with an attribute parsing...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, lastElementName + white + 2), _filePos, " parse an xml end with an attribute parsing..."));
|
||||
return false;
|
||||
}
|
||||
boolean simpleQuoteCase = false;
|
||||
@ -64,7 +68,7 @@ public class ParseXml {
|
||||
for (int iii = lastElementName + white + 2; iii < _data.length(); iii++) {
|
||||
Tools.drawElementParsed(_data.charAt(iii), _filePos);
|
||||
if (_filePos.check(_data.charAt(iii)) == true) {
|
||||
parsingProperty.createError(_data, iii, _filePos, "unexpected '\\n' in an attribute parsing");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, iii), _filePos, "unexpected '\\n' in an attribute parsing"));
|
||||
return false;
|
||||
}
|
||||
if (_data.charAt(iii) != ' ' && _data.charAt(iii) != '/' && _data.charAt(iii) != '?' && _data.charAt(iii) != '>') {
|
||||
@ -119,7 +123,7 @@ public class ParseXml {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "text CDATA got end of file without finding end node");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "text CDATA got end of file without finding end node"));
|
||||
_pos.value = _data.length();
|
||||
return false;
|
||||
}
|
||||
@ -156,7 +160,7 @@ public class ParseXml {
|
||||
}
|
||||
}
|
||||
_pos.value = _data.length();
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "comment got end of file without finding end node");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "comment got end of file without finding end node"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -171,7 +175,7 @@ public class ParseXml {
|
||||
}
|
||||
if (_data.charAt(iii) == '>' || _data.charAt(iii) == '<') {
|
||||
// an error occured :
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, " find '>' or '<' instead of '?>'");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, " find '>' or '<' instead of '?>'"));
|
||||
return false;
|
||||
}
|
||||
if (_data.charAt(iii) == '?' && _data.charAt(iii + 1) == '>') {
|
||||
@ -190,7 +194,7 @@ public class ParseXml {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Text got end of file without finding end node");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Text got end of file without finding end node"));
|
||||
_pos.value = _data.length();
|
||||
return false;
|
||||
}
|
||||
@ -211,7 +215,7 @@ public class ParseXml {
|
||||
if (_data.charAt(iii) == '/') {
|
||||
// standalone node or error...
|
||||
if (iii + 1 >= _data.length()) {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find end of files ... == > bad case");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find end of files ... == > bad case"));
|
||||
return false;
|
||||
}
|
||||
// TODO : Can have white spaces ....
|
||||
@ -220,7 +224,7 @@ public class ParseXml {
|
||||
return true;
|
||||
}
|
||||
// error
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find / without > char ...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find / without > char ..."));
|
||||
return false;
|
||||
}
|
||||
if (Tools.checkAvaillable(_data.charAt(iii), true) == true) {
|
||||
@ -233,11 +237,12 @@ public class ParseXml {
|
||||
continue;
|
||||
}
|
||||
if (Tools.isWhiteChar(_data.charAt(iii)) == false) {
|
||||
parsingProperty.createError(_data, iii, _filePos, "Find an unknow element : '" + _data.charAt(iii) + "'");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, iii), _filePos, "Find an unknow element : '" + _data.charAt(iii) + "'"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Unexpecting end of parsing exml::internal::Element : '" + nameElement + "' == > check if the '/>' is set or the end of element");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos,
|
||||
"Unexpecting end of parsing exml::internal::Element : '" + nameElement + "' == > check if the '/>' is set or the end of element"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -269,24 +274,26 @@ public class ParseXml {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Text got end of file without finding end node");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Text got end of file without finding end node"));
|
||||
_pos.value = _data.length();
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object parse(final String data) throws ExmlBuilderException {
|
||||
|
||||
public Object parse(final String data, final ParsingProperty property) throws ExmlBuilderException, ExmlParserErrorMulti {
|
||||
Log.verbose("Start parsing document (type: string) size=" + data.length());
|
||||
// came from char == > force in utf8 ...
|
||||
final FilePos pos = new FilePos(1, 0);
|
||||
final PositionParsing parsePos = new PositionParsing();
|
||||
final ParsingProperty property = new ParsingProperty();
|
||||
final Object rootNode = this.builder.newRoot();
|
||||
if (subParseElement(rootNode, null, data, parsePos, pos, property) == true) {
|
||||
return rootNode;
|
||||
}
|
||||
return null;
|
||||
|
||||
final Object rootNode = this.builder.newRoot();
|
||||
subParseElement(rootNode, null, data, parsePos, pos, property);
|
||||
if (property.isErrorDetected() == true) {
|
||||
if (property.isThrowOnError() == true) {
|
||||
throw new ExmlParserErrorMulti("Parsing error multiple error detected", property.getErrors());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -311,14 +318,14 @@ public class ParseXml {
|
||||
final int white = Tools.countWhiteChar(_data, iii + 1, tmpPos);
|
||||
if (iii + white + 1 >= _data.length()) {
|
||||
_filePos.add(tmpPos);
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "End file with '<' char == > invalide XML");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<' char == > invalide XML"));
|
||||
_pos.value = iii + white;
|
||||
return false;
|
||||
}
|
||||
// Detect type of the element:
|
||||
if (_data.charAt(iii + white + 1) == '>') {
|
||||
_filePos.add(tmpPos);
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find '>' with no element in the element...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find '>' with no element in the element..."));
|
||||
_pos.value = iii + white + 1;
|
||||
return false;
|
||||
}
|
||||
@ -326,7 +333,7 @@ public class ParseXml {
|
||||
tmpPos.increment();
|
||||
// TODO : white space ...
|
||||
if (Tools.checkAvaillable(_data.charAt(iii + white + 2), true) == false) {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find unavaillable name in the Declaration node...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find unavaillable name in the Declaration node..."));
|
||||
_pos.value = iii + white + 1;
|
||||
return false;
|
||||
}
|
||||
@ -343,8 +350,10 @@ public class ParseXml {
|
||||
tmpPos.check(_data.charAt(jjj));
|
||||
}
|
||||
String tmpname = _data.substring(iii + white + 2, endPosName + 1);
|
||||
if (parsingProperty.getCaseSensitive() == true) {
|
||||
if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) {
|
||||
tmpname = tmpname.toLowerCase();
|
||||
} else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) {
|
||||
tmpname = tmpname.toUpperCase();
|
||||
}
|
||||
// Find declaration marker
|
||||
final Object declaration = this.builder.newDeclaration(parent, tmpname);
|
||||
@ -361,17 +370,18 @@ public class ParseXml {
|
||||
tmpPos.increment();
|
||||
// Find special block element
|
||||
if (iii + white + 2 >= _data.length()) {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "End file with '<!' chars == > invalide XML");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<!' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
if (_data.charAt(iii + white + 2) == '-') {
|
||||
tmpPos.increment();
|
||||
if (iii + white + 3 >= _data.length()) {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "End file with '<!-' chars == > invalide XML");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<!-' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
if (_data.charAt(iii + white + 3) != '-') {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Element parse with '<!-" + _data.charAt(iii + 3) + "' chars == > invalide XML");
|
||||
parsingProperty
|
||||
.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Element parse with '<!-" + _data.charAt(iii + 3) + "' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
tmpPos.increment();
|
||||
@ -385,13 +395,14 @@ public class ParseXml {
|
||||
} else if (_data.charAt(iii + white + 2) == '[') {
|
||||
tmpPos.increment();
|
||||
if (iii + white + 8 >= _data.length()) {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "End file with '<![' chars == > invalide XML");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<![' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
if (_data.charAt(iii + white + 3) != 'C' || _data.charAt(iii + white + 4) != 'D' || _data.charAt(iii + white + 5) != 'A' || _data.charAt(iii + white + 6) != 'T'
|
||||
|| _data.charAt(iii + white + 7) != 'A' || _data.charAt(iii + white + 8) != '[') {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Element parse with '<![" + _data.charAt(iii + white + 3) + _data.charAt(iii + white + 4)
|
||||
+ _data.charAt(iii + white + 5) + _data.charAt(iii + white + 6) + _data.charAt(iii + white + 7) + _data.charAt(iii + white + 8) + "' chars == > invalide XML");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos,
|
||||
"Element parse with '<![" + _data.charAt(iii + white + 3) + _data.charAt(iii + white + 4) + _data.charAt(iii + white + 5) + _data.charAt(iii + white + 6)
|
||||
+ _data.charAt(iii + white + 7) + _data.charAt(iii + white + 8) + "' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
tmpPos.add(6);
|
||||
@ -403,7 +414,8 @@ public class ParseXml {
|
||||
}
|
||||
iii = _pos.value;
|
||||
} else {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "End file with '<!" + _data.charAt(iii + white + 2) + "' chars == > invalide XML");
|
||||
parsingProperty
|
||||
.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<!" + _data.charAt(iii + white + 2) + "' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
@ -422,11 +434,14 @@ public class ParseXml {
|
||||
}
|
||||
tmpPos.check(_data.charAt(jjj));
|
||||
}
|
||||
String tmpname = _data.substring(iii + white + 2, endPosName + 1);
|
||||
final String tmpname = _data.substring(iii + white + 2, endPosName + 1);
|
||||
String tmpnameCheck = tmpname;
|
||||
String nameElementCheck = nameElement;
|
||||
if (parsingProperty.getCaseSensitive() == true) {
|
||||
tmpname = tmpname.toLowerCase();
|
||||
tmpnameCheck = tmpname.toLowerCase();
|
||||
nameElementCheck = nameElement.toLowerCase();
|
||||
}
|
||||
if (tmpname.contentEquals(nameElement) == true) {
|
||||
if (tmpnameCheck.contentEquals(nameElementCheck) == true) {
|
||||
// find end of node :
|
||||
// find > element ...
|
||||
for (int jjj = endPosName + 1; jjj < _data.length(); jjj++) {
|
||||
@ -440,18 +455,19 @@ public class ParseXml {
|
||||
return true;
|
||||
} else if (_data.charAt(jjj) != '\r' && _data.charAt(jjj) != ' ' && _data.charAt(jjj) != '\t') {
|
||||
_filePos.add(tmpPos);
|
||||
parsingProperty.createError(_data, jjj, _filePos, "End node error : have data inside end node other than [ \\n\\t\\r] " + nameElement + "'");
|
||||
parsingProperty.createError(
|
||||
new ExmlParserError(Tools.extractLine(_data, jjj), _filePos, "End node error : have data inside end node other than [ \\n\\t\\r] " + nameElement + "'"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "End node error : '" + tmpname + "' != '" + nameElement + "'");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End node error : '" + tmpname + "' != '" + nameElement + "'"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (_data.charAt(iii + white + 1) == '>') {
|
||||
// end of something == > this is really bad
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find '>' chars == > invalide XML");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find '>' chars == > invalide XML"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -470,16 +486,20 @@ public class ParseXml {
|
||||
tmpPos.check(_data.charAt(jjj));
|
||||
}
|
||||
String tmpname = _data.substring(iii + white + 1, endPosName + 1);
|
||||
if (parsingProperty.getCaseSensitive() == true) {
|
||||
final String tmpnameOriginal = tmpname;
|
||||
if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) {
|
||||
tmpname = tmpname.toLowerCase();
|
||||
} else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) {
|
||||
tmpname = tmpname.toUpperCase();
|
||||
}
|
||||
|
||||
Log.debug("find node named : '" + tmpname + "'");
|
||||
// find text:
|
||||
final Object element = this.builder.newElement(parent, tmpname);
|
||||
_pos.value = endPosName + 1;
|
||||
_filePos.add(tmpPos);
|
||||
Log.verbose("start parse : 'element' named='" + tmpname + "'");
|
||||
if (iParseElement(element, tmpname, _data, _pos, _filePos, parsingProperty) == false) {
|
||||
if (iParseElement(element, tmpnameOriginal, _data, _pos, _filePos, parsingProperty) == false) {
|
||||
return false;
|
||||
}
|
||||
iii = _pos.value;
|
||||
@ -487,11 +507,11 @@ public class ParseXml {
|
||||
}
|
||||
_filePos.add(tmpPos);
|
||||
// here we have an error :
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find an ununderstanding element : '" + _data.charAt(iii + white + 1) + "'");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find an ununderstanding element : '" + _data.charAt(iii + white + 1) + "'"));
|
||||
return false;
|
||||
} else {
|
||||
if (_data.charAt(iii) == '>') {
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Find elemement '>' == > no reason to be here ...");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find elemement '>' == > no reason to be here ..."));
|
||||
return false;
|
||||
}
|
||||
// might to be data text ...
|
||||
@ -511,7 +531,7 @@ public class ParseXml {
|
||||
if (nameElement == null) {
|
||||
return true;
|
||||
}
|
||||
parsingProperty.createError(_data, _pos.value, _filePos, "Did not find end of the exml::internal::Element : '" + nameElement + "'");
|
||||
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Did not find end of the Element : '" + nameElement + "'"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +1,78 @@
|
||||
package org.atriasoft.exml.parser;
|
||||
|
||||
import org.atriasoft.exml.internal.FilePos;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.atriasoft.exml.exception.ExmlParserError;
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
import org.atriasoft.exml.internal.Tools;
|
||||
|
||||
public class ParsingProperty {
|
||||
private boolean caseSensitive; //!< check the case sensitive of the nodes and attribute
|
||||
private boolean writeErrorWhenDetexted; //!< Request print error in parsing just when detected
|
||||
|
||||
private String comment; //!< Comment on the error;
|
||||
private String Line; //!< Parse line error (copy);
|
||||
private FilePos filePos; //!< position of the error
|
||||
/// check the case sensitive of the nodes (end marker) and attribute (duplicates)
|
||||
private boolean caseSensitive = true;
|
||||
// Mode to store the Element name or the Attibute name
|
||||
private StoreMode storeMode = StoreMode.NORMAL;
|
||||
/// write error when not throw on error.
|
||||
private boolean writeError = false;
|
||||
/// throw when an error when it is detected (if permissive XML it throw only at the end of parsing).
|
||||
private boolean throwOnError = true;
|
||||
/// Permissive XML parsing (allows some errors must not be critical).
|
||||
private boolean permisiveXML = false;
|
||||
// List of all error detected
|
||||
private final List<ExmlParserError> errors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ParsingProperty() {
|
||||
this.caseSensitive = false;
|
||||
this.writeErrorWhenDetexted = true;
|
||||
this.comment = "";
|
||||
this.Line = "";
|
||||
this.filePos = new FilePos(0, 0);
|
||||
public ParsingProperty() {}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param caseSensitive set the parsing of value is case sensitive.
|
||||
* @param writeError Write all error when detected.
|
||||
* @param throwOnError throw an error when parsing fail (if permissiveXml, it throw only at the end).
|
||||
* @param permisiveXML Allow error and try to continue the parsing it is possible.
|
||||
*/
|
||||
public ParsingProperty(final boolean caseSensitive, final boolean writeError, final boolean throwOnError, final boolean permisiveXML) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
this.writeError = writeError;
|
||||
this.throwOnError = throwOnError;
|
||||
this.permisiveXML = permisiveXML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an error in the parsing (call by the syetm for error management)
|
||||
* @param[in] _data string of chat is wrong
|
||||
* @param[in] _pos Position in the file
|
||||
* @param[in] _filePos human position of the error
|
||||
* @param[in] _comment Error string to display
|
||||
* Add an error in the parsing of the XML (the function will select if we need to throw, print or ...)
|
||||
* @param error the error to throw or keep.
|
||||
* @return true if the parsing will stop
|
||||
* @throws ExmlParserError the error injected if user request it.
|
||||
*/
|
||||
public void createError(final String _data, final int _pos, final FilePos _filePos, final String _comment) {
|
||||
this.comment = _comment;
|
||||
this.Line = Tools.extract_line(_data, _pos);
|
||||
this.filePos = _filePos;
|
||||
if (this.writeErrorWhenDetexted == true) {
|
||||
displayError();
|
||||
public boolean createError(final ExmlParserError error) throws ExmlParserError {
|
||||
// need display the error
|
||||
if (this.writeError == true) {
|
||||
displayError(error);
|
||||
}
|
||||
// need throw the error
|
||||
if (this.throwOnError == true && this.permisiveXML == false) {
|
||||
throw error;
|
||||
}
|
||||
// Keep it in case
|
||||
this.errors.add(error);
|
||||
return this.permisiveXML == false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request Display in log all the errors.
|
||||
*/
|
||||
public void displayError() {
|
||||
this.errors.forEach(o -> displayError(o));
|
||||
}
|
||||
|
||||
/**
|
||||
* Request display in log of the error
|
||||
* @param error The error to display.
|
||||
*/
|
||||
public void displayError() {
|
||||
if (this.comment.length() == 0) {
|
||||
Log.error("No error detected ???");
|
||||
return;
|
||||
}
|
||||
Log.error(this.filePos + " " + this.comment + "\n" + this.Line + "\n" + Tools.createPosPointer(this.Line, this.filePos.getCol()));
|
||||
//Log.critical("detect error");
|
||||
public void displayError(final ExmlParserError error) {
|
||||
Log.error(error.getFilePos() + " " + error.getMessage() + "\n" + error.getDataLine() + "\n" + Tools.createPosPointer(error.getDataLine(), error.getFilePos().getCol()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,14 +89,53 @@ public class ParsingProperty {
|
||||
* @return false Does not display error (get it at end)
|
||||
*/
|
||||
public boolean getDisplayError() {
|
||||
return this.writeErrorWhenDetexted;
|
||||
return this.writeError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all error detected in the XML
|
||||
* @return Immutable list of error (order by arrival)
|
||||
*/
|
||||
public List<ExmlParserError> getErrors() {
|
||||
return Collections.unmodifiableList(this.errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current storing mode
|
||||
* @return store element and attribute values
|
||||
*/
|
||||
public StoreMode getStoreMode() {
|
||||
return this.storeMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is error has been detected
|
||||
* @return true if some error are stored.
|
||||
*/
|
||||
public boolean isErrorDetected() {
|
||||
return this.errors.isEmpty() == false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissive value
|
||||
* @return true if permissive mode is enable
|
||||
*/
|
||||
public boolean isPermisiveXML() {
|
||||
return this.permisiveXML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if throw on error
|
||||
* @return true if it throw on error
|
||||
*/
|
||||
public boolean isThrowOnError() {
|
||||
return this.throwOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or diasable the case sensitive (must be done before the call of parsing)
|
||||
* @param[in] _val true if enable; false else.
|
||||
*/
|
||||
// TODO: Naming error, it is insensitive ...
|
||||
public void setCaseSensitive(final boolean _val) {
|
||||
this.caseSensitive = _val;
|
||||
}
|
||||
@ -82,6 +145,30 @@ public class ParsingProperty {
|
||||
* @param[in] _value true: display error, false not display error (get it at end)
|
||||
*/
|
||||
public void setDisplayError(final boolean _value) {
|
||||
this.writeErrorWhenDetexted = _value;
|
||||
this.writeError = _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permissive value.
|
||||
* @param permisiveXML new value of permissive parsing.
|
||||
*/
|
||||
public void setPermisiveXML(final boolean permisiveXML) {
|
||||
this.permisiveXML = permisiveXML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new storing mode for Element and Attributes
|
||||
* @param storeMode new Storing mode
|
||||
*/
|
||||
public void setStoreMode(final StoreMode storeMode) {
|
||||
this.storeMode = storeMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set throwing on error (if permissive, it throw at the end of parsing)
|
||||
* @param throwOnError true if it throw on error.
|
||||
*/
|
||||
public void setThrowOnError(final boolean throwOnError) {
|
||||
this.throwOnError = throwOnError;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.atriasoft.exml.internal;
|
||||
package org.atriasoft.exml.parser;
|
||||
|
||||
public class PositionParsing {
|
||||
public int value = 0;
|
||||
|
||||
}
|
7
src/org/atriasoft/exml/parser/StoreMode.java
Normal file
7
src/org/atriasoft/exml/parser/StoreMode.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.atriasoft.exml.parser;
|
||||
|
||||
public enum StoreMode {
|
||||
NORMAL,
|
||||
UPPERCASE,
|
||||
LOWERCASE,
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
package org.atriasoft.exml.internal;
|
||||
package org.atriasoft.exml.parser;
|
||||
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
|
||||
public class Tools {
|
||||
/**
|
||||
@ -88,7 +90,7 @@ public class Tools {
|
||||
}
|
||||
}
|
||||
|
||||
public static String extract_line(final String data, final int _pos) {
|
||||
public static String extractLine(final String data, final int _pos) {
|
||||
// search back : '\n'
|
||||
int startPos = data.lastIndexOf('\n', _pos);
|
||||
if (startPos == _pos) {
|
112
src/org/atriasoft/exml/serializer/SerializerXml.java
Normal file
112
src/org/atriasoft/exml/serializer/SerializerXml.java
Normal file
@ -0,0 +1,112 @@
|
||||
package org.atriasoft.exml.serializer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
import org.atriasoft.exml.model.XmlAttribute;
|
||||
import org.atriasoft.exml.model.XmlAttributeList;
|
||||
import org.atriasoft.exml.model.XmlComment;
|
||||
import org.atriasoft.exml.model.XmlDeclaration;
|
||||
import org.atriasoft.exml.model.XmlElement;
|
||||
import org.atriasoft.exml.model.XmlNode;
|
||||
import org.atriasoft.exml.model.XmlNodeType;
|
||||
import org.atriasoft.exml.model.XmlText;
|
||||
import org.atriasoft.exml.parser.Tools;
|
||||
|
||||
public class SerializerXml {
|
||||
|
||||
public static void serialize(final XmlNode node, final StringBuilder data, final int indent) {
|
||||
if (node instanceof XmlElement) {
|
||||
serializeElement((XmlElement) node, data, indent);
|
||||
} else if (node instanceof XmlText) {
|
||||
serializeText((XmlText) node, data, indent);
|
||||
} else if (node instanceof XmlDeclaration) {
|
||||
serializeDeclaration((XmlDeclaration) node, data, indent);
|
||||
} else if (node instanceof XmlComment) {
|
||||
serializeComment((XmlComment) node, data, indent);
|
||||
} else {
|
||||
// TODO throw an error ...
|
||||
}
|
||||
}
|
||||
|
||||
private static void serializeAttribute(final XmlAttribute attribute, final StringBuilder data, final int indent) {
|
||||
data.append(" ");
|
||||
data.append(attribute.getName());
|
||||
data.append("=\"");
|
||||
data.append(attribute.getValue());
|
||||
data.append("\"");
|
||||
}
|
||||
|
||||
private static void serializeAttributeList(final XmlAttributeList list, final StringBuilder data, final int indent) {
|
||||
for (int iii = 0; iii < list.getAttributes().size(); iii++) {
|
||||
serializeAttribute(list.getAttributes().get(iii), data, indent);
|
||||
}
|
||||
}
|
||||
|
||||
private static void serializeComment(final XmlComment comment, final StringBuilder data, final int indent) {
|
||||
Tools.addIndent(data, indent);
|
||||
data.append("<!--");
|
||||
data.append(comment.getValue());
|
||||
data.append("-->\n");
|
||||
}
|
||||
|
||||
private static void serializeDeclaration(final XmlDeclaration declaration, final StringBuilder data, final int indent) {
|
||||
Tools.addIndent(data, indent);
|
||||
data.append("<?");
|
||||
data.append(declaration.getValue());
|
||||
serializeAttributeList(declaration, data, indent);
|
||||
data.append("?>\n");
|
||||
|
||||
}
|
||||
|
||||
private static void serializeElement(final XmlElement element, final StringBuilder data, final int indent) {
|
||||
|
||||
Tools.addIndent(data, indent);
|
||||
data.append("<");
|
||||
data.append(element.getValue());
|
||||
serializeAttributeList(element, data, indent);
|
||||
|
||||
final List<XmlNode> nodes = element.getNodes();
|
||||
if (nodes.size() > 0) {
|
||||
if (nodes.size() == 1 && nodes.get(0) != null && nodes.get(0).getType() == XmlNodeType.TEXT && ((XmlText) nodes.get(0)).countLines() == 1) {
|
||||
data.append(">");
|
||||
serialize(nodes.get(0), data, 0);
|
||||
Log.verbose(" generate : '" + data + "'");
|
||||
} else {
|
||||
data.append(">\n");
|
||||
for (int iii = 0; iii < nodes.size(); iii++) {
|
||||
if (nodes.get(iii) != null) {
|
||||
serialize(nodes.get(iii), data, indent + 1);
|
||||
}
|
||||
}
|
||||
Tools.addIndent(data, indent);
|
||||
}
|
||||
data.append("</");
|
||||
data.append(element.getValue());
|
||||
data.append(">\n");
|
||||
} else {
|
||||
data.append("/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
public static void serializeRoot(final XmlElement root, final StringBuilder data) {
|
||||
for (int iii = 0; iii < root.getNodes().size(); iii++) {
|
||||
final XmlNode node = root.getNodes().get(iii);
|
||||
serialize(node, data, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void serializeText(final XmlText text, final StringBuilder data, final int indent) {
|
||||
data.append(Tools.replaceSpecialCharOut(text.getValue()));
|
||||
}
|
||||
/* CDATA generation ... maybe to add later ...
|
||||
@Override
|
||||
protected boolean iGenerate(final StringBuilder _data, final int _indent) {
|
||||
_data.append("<![CDATA[");
|
||||
_data.append(this.value);
|
||||
_data.append("]]>");
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
}
|
@ -5,8 +5,9 @@
|
||||
*/
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.Document;
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.model.XmlNode;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
class ExmlLocal {
|
||||
@ -16,24 +17,25 @@ class ExmlLocal {
|
||||
}
|
||||
|
||||
public static void test(final String _ref, final String _input, final int _errorPos, final boolean _caseInSensitive) {
|
||||
final Document doc = new Document();
|
||||
//doc.setCaseSensitive(!_caseInSensitive);
|
||||
Log.verbose("parse : \n" + _input);
|
||||
final boolean retParse = Exml.parse(_input);
|
||||
if (_errorPos == 1) {
|
||||
Assertions.assertEquals(retParse, false);
|
||||
return;
|
||||
} else {
|
||||
Assertions.assertEquals(retParse, true);
|
||||
XmlNode root = null;
|
||||
try {
|
||||
root = Exml.parse(_input);
|
||||
if (_errorPos == 1) {
|
||||
Assertions.fail("Must have detected an error");
|
||||
return;
|
||||
}
|
||||
} catch (final ExmlBuilderException e) {
|
||||
if (_errorPos == 1) {
|
||||
return;
|
||||
} else {
|
||||
Assertions.fail("Must have NOT detected an error");
|
||||
}
|
||||
}
|
||||
final StringBuilder out = new StringBuilder();
|
||||
final boolean retGenerate = doc.generate(out);
|
||||
if (_errorPos == 2) {
|
||||
Assertions.assertEquals(retGenerate, false);
|
||||
return;
|
||||
} else {
|
||||
Assertions.assertEquals(retGenerate, true);
|
||||
}
|
||||
// TODO: 2 is for failing in generate ...
|
||||
Exml.generate(root, out);
|
||||
final String data = out.toString();
|
||||
if (_errorPos == 3) {
|
||||
Assertions.assertNotEquals(_ref, data);
|
||||
|
@ -5,11 +5,10 @@
|
||||
*/
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.XmlAttribute;
|
||||
import org.atriasoft.exml.Document;
|
||||
import org.atriasoft.exml.XmlElement;
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
|
||||
import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
|
||||
import org.atriasoft.exml.model.XmlAttribute;
|
||||
import org.atriasoft.exml.model.XmlElement;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -28,7 +27,6 @@ public class ExmlTestAttribute {
|
||||
|
||||
@Test
|
||||
public void clear() {
|
||||
|
||||
final XmlAttribute myAttribute = new XmlAttribute("nameAttribute", "valueAttribute");
|
||||
myAttribute.clear();
|
||||
}
|
||||
@ -51,7 +49,6 @@ public class ExmlTestAttribute {
|
||||
|
||||
@Test
|
||||
public void exist() {
|
||||
|
||||
final XmlElement elem = new XmlElement("elem");
|
||||
elem.setAttribute("valA", "plop");
|
||||
Assertions.assertEquals(elem.existAttribute("valA"), true);
|
||||
@ -60,43 +57,29 @@ public class ExmlTestAttribute {
|
||||
|
||||
@Test
|
||||
public void get() {
|
||||
|
||||
final XmlElement elem = new XmlElement("elem");
|
||||
elem.setAttribute("valA", "plop");
|
||||
try {
|
||||
Assertions.assertEquals(elem.getAttribute("valA"), "plop");
|
||||
} catch (final ExmlAttributeDoesNotExist e) {
|
||||
Assertions.fail("Should Not have thrown an exception");
|
||||
}
|
||||
final String attributeValue = Assertions.assertDoesNotThrow(() -> elem.getAttribute("valA"));
|
||||
Assertions.assertEquals(attributeValue, "plop");
|
||||
Assertions.assertThrows(ExmlAttributeDoesNotExist.class, () -> elem.getAttribute("qsdfsdf"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getpair() {
|
||||
|
||||
final XmlElement elem = new XmlElement("elem");
|
||||
elem.setAttribute("valA", "coucou");
|
||||
try {
|
||||
Assertions.assertEquals(elem.getAttrPair(0).first, "valA");
|
||||
Assertions.assertEquals(elem.getAttrPair(0).second, "coucou");
|
||||
} catch (final ExmlAttributeDoesNotExist e) {
|
||||
Assertions.fail("Should Not have thrown an exception");
|
||||
}
|
||||
final String first = Assertions.assertDoesNotThrow(() -> elem.getAttrPair(0).first);
|
||||
Assertions.assertEquals(first, "valA");
|
||||
final String second = Assertions.assertDoesNotThrow(() -> elem.getAttrPair(0).second);
|
||||
Assertions.assertEquals(second, "coucou");
|
||||
Assertions.assertThrows(ExmlAttributeDoesNotExist.class, () -> elem.getAttrPair(1));
|
||||
Assertions.assertThrows(ExmlAttributeDoesNotExist.class, () -> elem.getAttrPair(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moveInAllElement() {
|
||||
final Document doc = new Document();
|
||||
doc.parse("<elem valA=\"plop\"/>");
|
||||
XmlElement elem;
|
||||
try {
|
||||
elem = (XmlElement) doc.getNode("elem");
|
||||
} catch (final ExmlNodeDoesNotExist e) {
|
||||
Assertions.fail("Should Not have thrown an exception");
|
||||
return;
|
||||
}
|
||||
final XmlElement root = Assertions.assertDoesNotThrow(() -> Exml.parse("<elem valA=\"plop\"/>"));
|
||||
final XmlElement elem = Assertions.assertDoesNotThrow(() -> (XmlElement) root.getNode("elem"));
|
||||
for (final XmlAttribute it : elem.getAttributes()) {
|
||||
Assertions.assertEquals(it.getName(), "valA");
|
||||
Assertions.assertEquals(it.getValue(), "plop");
|
||||
@ -114,7 +97,6 @@ public class ExmlTestAttribute {
|
||||
|
||||
@Test
|
||||
public void setGetName() {
|
||||
|
||||
final XmlAttribute myAttribute = new XmlAttribute("nameAttribute", "valueAttribute");
|
||||
Assertions.assertEquals(myAttribute.getName(), "nameAttribute");
|
||||
myAttribute.setName("newName");
|
||||
@ -123,7 +105,6 @@ public class ExmlTestAttribute {
|
||||
|
||||
@Test
|
||||
public void setGetValue() {
|
||||
|
||||
final XmlAttribute myAttribute = new XmlAttribute("nameAttribute", "valueAttribute");
|
||||
Assertions.assertEquals(myAttribute.getValue(), "valueAttribute");
|
||||
myAttribute.setValue("new value");
|
||||
@ -132,31 +113,20 @@ public class ExmlTestAttribute {
|
||||
|
||||
@Test
|
||||
public void setterNew() {
|
||||
|
||||
final XmlElement elem = new XmlElement("elem");
|
||||
elem.setAttribute("valA", "coucou");
|
||||
try {
|
||||
Assertions.assertEquals(elem.getAttribute("valA"), "coucou");
|
||||
} catch (final ExmlAttributeDoesNotExist e) {
|
||||
Assertions.fail("Should Not have thrown an exception");
|
||||
}
|
||||
final String attributeValue = Assertions.assertDoesNotThrow(() -> elem.getAttribute("valA"));
|
||||
Assertions.assertEquals(attributeValue, "coucou");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setterRewrite() {
|
||||
|
||||
final XmlElement elem = new XmlElement("elem");
|
||||
elem.setAttribute("valA", "coucou");
|
||||
try {
|
||||
Assertions.assertEquals(elem.getAttribute("valA"), "coucou");
|
||||
} catch (final ExmlAttributeDoesNotExist e) {
|
||||
Assertions.fail("Should Not have thrown an exception");
|
||||
}
|
||||
String attributeValue = Assertions.assertDoesNotThrow(() -> elem.getAttribute("valA"));
|
||||
Assertions.assertEquals(attributeValue, "coucou");
|
||||
elem.setAttribute("valA", "coucou2");
|
||||
try {
|
||||
Assertions.assertEquals(elem.getAttribute("valA"), "coucou2");
|
||||
} catch (final ExmlAttributeDoesNotExist e) {
|
||||
Assertions.fail("Should Not have thrown an exception");
|
||||
}
|
||||
attributeValue = Assertions.assertDoesNotThrow(() -> elem.getAttribute("valA"));
|
||||
Assertions.assertEquals(attributeValue, "coucou2");
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,8 @@
|
||||
*/
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.Document;
|
||||
import org.atriasoft.exml.XmlElement;
|
||||
import org.atriasoft.exml.TextCDATA;
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.model.XmlElement;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -18,23 +17,10 @@ public class ExmlTestCData {
|
||||
Log.verbose("----------------------------------------------------------------");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generate() {
|
||||
final Document doc = new Document();
|
||||
doc.append(new TextCDATA("Text &é<>examp]le]] ..."));
|
||||
doc.append(new TextCDATA("Text &é<>examp]le]] ..."));
|
||||
final String out = doc.getText();
|
||||
doc.parse("<elem><![CDATA[Text &é<>examp]le]] ...]]></elem>");
|
||||
Assertions.assertEquals("<![CDATA[Text &é<>examp]le]] ...]]><![CDATA[Text &é<>examp]le]] ...]]>", out);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseCDATA() {
|
||||
final Document doc = new Document();
|
||||
doc.parse("<elem><![CDATA[Text &é<>examp]le]] ...]]></elem>");
|
||||
final XmlElement elem = Assertions.assertDoesNotThrow(() -> {
|
||||
return (XmlElement) doc.getNode("elem");
|
||||
});
|
||||
final XmlElement root = Assertions.assertDoesNotThrow(() -> Exml.parse("<elem><![CDATA[Text &é<>examp]le]] ...]]></elem>"));
|
||||
final XmlElement elem = Assertions.assertDoesNotThrow(() -> (XmlElement) root.getNode("elem"));
|
||||
Assertions.assertEquals("Text &é<>examp]le]] ...", elem.getText());
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
*/
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.XmlComment;
|
||||
import org.atriasoft.exml.XmlNode;
|
||||
import org.atriasoft.exml.XmlNodeType;
|
||||
import org.atriasoft.exml.model.XmlComment;
|
||||
import org.atriasoft.exml.model.XmlNode;
|
||||
import org.atriasoft.exml.model.XmlNodeType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -5,9 +5,9 @@
|
||||
*/
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.DeclarationXML;
|
||||
import org.atriasoft.exml.XmlNodeType;
|
||||
import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
|
||||
import org.atriasoft.exml.model.XmlDeclaration;
|
||||
import org.atriasoft.exml.model.XmlNodeType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -20,7 +20,7 @@ public class ExmlTestDeclarationXML {
|
||||
|
||||
@Test
|
||||
public void create() {
|
||||
final DeclarationXML myDeclarationXML = new DeclarationXML("1.0", "UTF-8", true);
|
||||
final XmlDeclaration myDeclarationXML = new XmlDeclaration("1.0", "UTF-8", true);
|
||||
Assertions.assertEquals(myDeclarationXML.getType(), XmlNodeType.DECLARATION);
|
||||
try {
|
||||
Assertions.assertEquals(myDeclarationXML.getAttribute("version"), "1.0");
|
||||
@ -34,8 +34,8 @@ public class ExmlTestDeclarationXML {
|
||||
@Test
|
||||
public void createAssignement() {
|
||||
|
||||
final DeclarationXML myDeclarationXML = new DeclarationXML("1.0", "UTF-8", true);
|
||||
final DeclarationXML myOtherDeclarationXML = myDeclarationXML.clone();
|
||||
final XmlDeclaration myDeclarationXML = new XmlDeclaration("1.0", "UTF-8", true);
|
||||
final XmlDeclaration myOtherDeclarationXML = myDeclarationXML.clone();
|
||||
Assertions.assertEquals(myDeclarationXML.getValue(), myOtherDeclarationXML.getValue());
|
||||
try {
|
||||
Assertions.assertEquals(myDeclarationXML.getAttribute("version"), myOtherDeclarationXML.getAttribute("version"));
|
||||
@ -48,8 +48,8 @@ public class ExmlTestDeclarationXML {
|
||||
|
||||
@Test
|
||||
public void createCopy() {
|
||||
final DeclarationXML myDeclarationXML = new DeclarationXML("1.0", "UTF-8", true);
|
||||
final DeclarationXML myOtherDeclarationXML = new DeclarationXML(myDeclarationXML);
|
||||
final XmlDeclaration myDeclarationXML = new XmlDeclaration("1.0", "UTF-8", true);
|
||||
final XmlDeclaration myOtherDeclarationXML = new XmlDeclaration(myDeclarationXML);
|
||||
Assertions.assertEquals(myDeclarationXML.getValue(), myOtherDeclarationXML.getValue());
|
||||
try {
|
||||
Assertions.assertEquals(myDeclarationXML.getAttribute("version"), myOtherDeclarationXML.getAttribute("version"));
|
||||
|
@ -5,11 +5,11 @@
|
||||
*/
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.Document;
|
||||
import org.atriasoft.exml.XmlElement;
|
||||
import org.atriasoft.exml.XmlNode;
|
||||
import org.atriasoft.exml.XmlNodeType;
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
|
||||
import org.atriasoft.exml.model.XmlElement;
|
||||
import org.atriasoft.exml.model.XmlNode;
|
||||
import org.atriasoft.exml.model.XmlNodeType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -114,9 +114,8 @@ public class ExmlTestElement {
|
||||
|
||||
@Test
|
||||
public void moveInAllElement() {
|
||||
final Document doc = new Document();
|
||||
doc.parse("<elem><elem1/><elem2/></elem>");
|
||||
for (final XmlNode it : doc.getNodes()) {
|
||||
final XmlElement root = Assertions.assertDoesNotThrow(() -> Exml.parse("<elem><elem1/><elem2/></elem>"));
|
||||
for (final XmlNode it : root.getNodes()) {
|
||||
final XmlElement elem = (XmlElement) it;
|
||||
Assertions.assertEquals("elem", elem.getValue());
|
||||
Assertions.assertEquals(2, elem.getNodes().size());
|
||||
|
@ -29,6 +29,11 @@ public class ExmlTestParseDeclaration {
|
||||
ExmlLocal.test("<?testDeclaration?>\n", "<?testDeclaration?>\n", -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseSensitiveBalise() {
|
||||
ExmlLocal.test("<Elem/>\n", "<Elem></elem>\n", -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiline() {
|
||||
ExmlLocal.test("<?xml attr=\"plop\"?>\n", "<?xml attr\n=\n\"plop\"?>\n", -1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user