public class XmlJzReader
extends java.lang.Object
XmlJzReader xmlReader = new XmlJzReader(); //instance to work, more as one file one after another xmlJzReader.readCfg(cfgFile); //configuration for next xmlRead() AnyClass data = new AnyClass(); //a proper output instance matching to the cfg xmlReader.readXml(xmlInputFile, data); //reads the xml file and stores read data.The configuration file contains the template of the xml file with paths to store the content in a proper user instance The paths is processed with
DataAccess.DatapathElement
. The configuration is hold in an instance of XmlCfg
.
Detail description of the config file see XmlCfg
.Modifier and Type | Class and Description |
---|---|
(package private) static class |
XmlJzReader.AttribToStore |
Modifier and Type | Field and Description |
---|---|
private boolean |
bUseNonSemanticDataStore |
(package private) XmlCfg |
cfg
To store the last used configuration, for parsing with the same config.
|
(package private) XmlCfg |
cfgCfg
Configuration to read a config file.
|
private XmlCfg.XmlCfgNode |
cfgNodeNonSemanticDataStore |
private int |
debugStopLine
It is able to set with
setDebugStop(int) |
private java.lang.String |
debugTag
It is able to set with
setDebugStopTag(String) |
protected LogMessage |
log |
(package private) java.util.Map<java.lang.String,java.lang.String> |
namespaces
Assignment between nameSpace-alias and nameSpace-value gotten from the xmlns:ns="value" declaration in the read XML file.
|
private java.util.Map<java.lang.String,java.lang.String> |
replaceChars |
(package private) int |
sizeBuffer
Size of the buffer to hold a part of the xml input file.
|
static java.lang.String |
version
Version, License and History:
2024-06-07: Important fix: An simple space after > but before \n or before < is also content!
|
(package private) XmlSequWriter |
xmlTestWriter |
Constructor and Description |
---|
XmlJzReader() |
XmlJzReader(LogMessage log) |
Modifier and Type | Method and Description |
---|---|
private void |
errMsg(int nr,
StringPartScan inp,
java.lang.CharSequence... txt) |
(package private) void |
finishElement(java.lang.Object parent,
java.lang.Object element,
DataAccess.DatapathElement elementStorePath)
This op is called on finishing of parsing a element with its sub content.
|
XmlCfg |
getCfg()
Gets the XmlCfg data for additional evaluation.
|
private XmlCfg.AttribDstCheck |
getCfgAttrib(java.lang.CharSequence sAttrNsName,
XmlCfg.XmlCfgNode cfgNode) |
(package private) java.lang.Object |
getDataForTheElement(java.lang.Object output,
DataAccess.DatapathElement elementStorePath,
java.lang.String[] attribValues)
Invokes the associated method to get/create the appropriate data instance for the element.
|
void |
openXmlTestOut(java.io.File fout)
Writes the parsed content without processing in this file.
|
private java.lang.String |
parseAttributes(StringPartScan inp,
java.lang.String tag,
XmlCfg.XmlCfgNode cfgNode,
java.util.List<XmlJzReader.AttribToStore>[] attribsToStore,
java.util.List<XmlJzReader.AttribToStore>[] namespacesToStore)
Parses all given Attributes from the XML element.
|
private java.lang.CharSequence |
parseContent(StringPartScan inp,
java.lang.StringBuilder buffer)
Reads the textual content of an element.
|
private void |
parseElement(StringPartScan inp,
java.lang.Object output,
XmlCfg.XmlCfgNode cfgNode,
int recursion)
Parse a whole element with all inner content
First the tag is parsed, then all attributes using
parseAttributes(StringPartScan, String, org.vishia.xmlReader.XmlCfg.XmlCfgNode, List[], List[]) . |
XmlCfg |
readCfg(java.io.File file)
Read the configuration file for this instance.
|
XmlCfg |
readCfgFromJar(java.lang.Class<?> clazz,
java.lang.String pathInJarFromClazz)
Read from a resource (file inside jar archive).
|
XmlCfg |
readCfgTxtFromJar(java.lang.Class<?> clazz,
java.lang.String pathInJarFromClazz)
Read from a resource (file inside jar archive).
|
java.lang.String |
readXml(java.io.File file,
java.lang.Object dst) |
java.lang.String |
readXml(java.io.File input,
java.lang.Object output,
XmlCfg xmlCfg)
Reads an xml file with a given config.
|
java.lang.String |
readXml(java.io.InputStream stream,
java.lang.String sInputPath,
java.lang.Object dst) |
java.lang.String |
readXml(java.io.InputStream input,
java.lang.String sInputPath,
java.lang.Object output,
XmlCfg xmlCfg)
Reads the xml content from an opened stream.
|
java.lang.String |
readXml(java.io.Reader stream,
java.lang.String sInputPath,
java.lang.Object dst) |
java.lang.String |
readXml(java.io.Reader input,
java.lang.String sInputPath,
java.lang.Object output,
XmlCfg xmlCfg)
Reads the xml content from an opened stream.
|
void |
readXml(StringPartScan input,
java.lang.Object output)
Reads the xml content from an StringPart.
|
void |
readXml(StringPartScan inp,
java.lang.Object output,
XmlCfg xmlCfg)
Core routine to read in whole XML stream.
|
java.lang.String |
readZipXml(java.io.File zipInput,
java.lang.String pathInZip,
java.lang.Object output)
Reads an xml File from a zipfile.
|
private java.lang.CharSequence |
replaceSpecialCharsInText(java.lang.CharSequence src)
Replaces the basic sequences < etc. and the UTF 16 <#xaaaa;
and replaces line feed with indent with one space.
|
void |
setCfg(XmlCfg cfg)
Set the CmlCfg with a Java-given structure, especially for config reading.
|
void |
setDebugStop(int line)
Only for internal debug.
|
void |
setDebugStopTag(java.lang.String stag) |
void |
setNamespaceEntry(java.lang.String key,
java.lang.String url)
This operation is only necessary if a name space declaration is missing
in the xml file to read.
|
private void |
storeAttrData(StringPartScan inp,
java.lang.Object output,
DataAccess.DatapathElement dstPath,
java.util.Map<java.lang.String,DataAccess.IntegerIx> attribNames,
java.lang.CharSequence sAttrName,
java.lang.CharSequence sAttrValue,
java.lang.String sTag)
Invokes the associated method to store the attribute value.
|
private void |
storeAttributesDueToSubCfgNode(XmlCfg.XmlCfgNode cfgNode,
java.util.List<XmlJzReader.AttribToStore> attribStore,
java.util.List<XmlJzReader.AttribToStore> namespacesStore,
java.util.Map<java.lang.String,DataAccess.IntegerIx> attribNames,
java.lang.String[] attribValues) |
private static void |
storeContent(java.lang.StringBuilder buffer,
XmlCfg.XmlCfgNode cfgNode,
java.lang.Object output,
DataAccess.DatapathElement contentStorePath,
java.util.Map<java.lang.String,DataAccess.IntegerIx> attribs,
java.lang.String[] attribValues) |
public static final java.lang.String version
XmlAddData_ifc
instance, if given as data on readXml(File, Object)
etc.
The config is only necessary for the namespace declaration, because the namespace alias are not anytime the same in a read XML.
The bUseNonSemanticDataStore
is set true if detected and a dummy config cfgNodeNonSemanticDataStore
is used instead not found config nodes on the elements.
Writing to the output is always done via the operations of XmlAddData_ifc
if bUseNonSemanticDataStore
is set.
#parseElement(StringPartScan, Object, org.vishia.xmlReader.XmlCfg.XmlCfgNode)
refactored.
Now it uses consequently the subtree if given. See documentation in LibreOffice.
readCfgTxtFromJar(Class, String)
parseContent(StringPartScan, StringBuilder)
#storeContent(StringBuilder, org.vishia.xmlReader.XmlCfg.XmlCfgNode, Object, Map[], String[])
.
#storeContent(StringBuilder, org.vishia.xmlReader.XmlCfg.XmlCfgNode, Object, Map[], String[])
:
the DataAccess.invokeMethod(org.vishia.util.DataAccess.DatapathElement, Class, Object, boolean, Object[], boolean)
was called with true for non exception, that is faulty. To detect writing errors in the xmlcfg file, exceptions are necessary.
finishElement(Object, Object, org.vishia.util.DataAccess.DatapathElement)
setNamespaceEntry(String, String)
Field
then the value is stored in this return field
independent whether it is used also as argument. This can be helpfully and it is a special condition lesser.
storeAttrData(StringPartScan, Object, org.vishia.util.DataAccess.DatapathElement, Map, CharSequence, CharSequence, String)
In the Xmlcfg file now you can use "tag"
as attribute value for a xmlinput:data="!CREATE_OPER(..., tag, ...)
now.
Additionally: If the attr="!OPERATION(?)"
does not use "value" as argument
and it returns a java.lang.reflect.Field then this field is used to store the attribute value, as also for a simple expression.
readCfg(File)
and readCfgFromJar(Class, String)
produces now a new instance of XmlCfg
data.
Before the read cfg data are written in the given instance of cfg
which means, immediately able to use,
but the older instance was destroyed. This new version is compatible with the old one (both activates updates the cfg
),
but now the reference to a older read config remain valid and can be reused for the now public readXml(File, Object, XmlCfg)
.
It means some XmlCfg
can be present and use for different reading approaches with the same XmlJzReader.
You can switch between config. This change was done primary because the older implementation was not really good able to document.
The older approach was firstly done to save memory space (prevent new instances).
But this is not true because the Garbage Collector does its work if necessary.
storeAttrData(StringPartScan, Object, org.vishia.util.DataAccess.DatapathElement, Map, CharSequence, CharSequence, String)
gets inp as info only for a better error msg.
#parseElement(StringPartScan, Object, org.vishia.xmlReader.XmlCfg.XmlCfgNode)
stores also a namespace definition in user data if required. See cfg.
errMsg(int, StringPartScan, CharSequence...)
as central routine if problems occur.
readXml(Reader, String, Object)
and readXml(StringPartScan, Object)
XmlSequWriter
for Test output the read content,
if openXmlTestOut(File)
is invoked. .
DataAccess
, handling of arguments on access routines changed.
XmlCfg cfg
final XmlCfg cfgCfg
private boolean bUseNonSemanticDataStore
private XmlCfg.XmlCfgNode cfgNodeNonSemanticDataStore
int sizeBuffer
private int debugStopLine
setDebugStop(int)
private java.lang.String debugTag
setDebugStopTag(String)
java.util.Map<java.lang.String,java.lang.String> namespaces
private final java.util.Map<java.lang.String,java.lang.String> replaceChars
XmlSequWriter xmlTestWriter
protected final LogMessage log
public XmlJzReader()
public XmlJzReader(LogMessage log)
public void setDebugStop(int line)
line
- public void setDebugStopTag(java.lang.String stag)
public void openXmlTestOut(java.io.File fout) throws java.io.IOException
xmlTestWriter
.
It is closed on end of JZtxtReader. It means this operation should be called
immediately before call of readXml(File, Object)
or also readCfg(File)
and all its abbreviations. It should not be called without a read Xml invocation
because otherwise the resource remains open.fout
- File to writejava.io.IOException
- if open failspublic void setNamespaceEntry(java.lang.String key, java.lang.String url)
key
- url
- public java.lang.String readXml(java.io.File input, java.lang.Object output, XmlCfg xmlCfg) throws java.io.IOException
readCfg(File)
or #readCfgFromJar(String)
.
This operation is used internally in for all read operations too. It is the common entry to read.input
- The xml fileoutput
- The empty data where the first operation is called or the first data are stored via reflection.xmlCfg
- Already read XmlCfg from a file using {readCfg(File)
} or readCfgFromJar(Class, String)
or alternatively a immediate prepared XmlCfg.
XmlCfg.newCfgCfg()
.
java.io.IOException
public java.lang.String readZipXml(java.io.File zipInput, java.lang.String pathInZip, java.lang.Object output)
#readXmlCfg(File)
was invoked before or the config will be read itself (with cfgCfg
as configuration).zipInput
- The zipfile itselfpathInZip
- The path of a file inside the zip fileoutput
- destination dataThrowable.getMessage()
.public java.lang.String readXml(java.io.InputStream input, java.lang.String sInputPath, java.lang.Object output, XmlCfg xmlCfg)
StringPartScan
class.
The StringPartScan
scans the XML syntax.
XmlJzReader
.input
- any opened InputStream. Typically it is an FileInputStream or InputStream from a ZipEntry
.sInputPath
- The path to the input stream, used for error hints while parsing.output
- Any output data. The structure should match to the xmlCfg.xmlCfg
- A configuration. It can be gotten via readCfg(File)
.public void readXml(StringPartScan input, java.lang.Object output) throws java.lang.Exception
StringPartScan
class.
The StringPartScan
scans the XML syntax.
XmlJzReader
.input
- any opened InputStream. Typically it is an FileInputStream or InputStream from a ZipEntry
.sInputPath
- The path to the input stream, used for error hints while parsing.output
- Any output data. The structure should match to the xmlCfg.xmlCfg
- A configuration. It can be gotten via readCfg(File)
.java.lang.Exception
public java.lang.String readXml(java.io.Reader input, java.lang.String sInputPath, java.lang.Object output, XmlCfg xmlCfg)
StringPartScan
class.
The StringPartScan
scans the XML syntax.
XmlJzReader
.input
- any opened InputStream. Typically it is an FileInputStream or InputStream from a ZipEntry
.sInputPath
- The path to the input stream, used for error hints while parsing.output
- Any output data. The structure should match to the xmlCfg.xmlCfg
- A configuration. It can be gotten via readCfg(File)
.public void readXml(StringPartScan inp, java.lang.Object output, XmlCfg xmlCfg) throws java.lang.Exception
inp
- A StringPartScan can be built from a String too, using StringPart.assign(CharSequence)
.
for file reading the constructor StringPartFromFileLines.StringPartFromFileLines(File)
is used.output
- the data to store the read content. Should match to the root instance in the cfg file.xmlCfg
- The used configuration (it does not access the cfg
if the instance, may call with cfg
.java.lang.Exception
private void parseElement(StringPartScan inp, java.lang.Object output, XmlCfg.XmlCfgNode cfgNode, int recursion) throws java.lang.Exception
parseAttributes(StringPartScan, String, org.vishia.xmlReader.XmlCfg.XmlCfgNode, List[], List[])
.
This parses stores only the values of the attributes in , and evaluate the CHECK attributes.
The attributes are stored in a ListgetCfgAttrib(CharSequence, org.vishia.xmlReader.XmlCfg.XmlCfgNode)
Not (old solution) with the immediately subCfgNode.
But the attribute values are not stored till now, because the output instance is not given.
XmlJzReader.AttribToStore.daccess
path.
this is done in storeAttributesDueToSubCfgNode(org.vishia.xmlReader.XmlCfg.XmlCfgNode, List, List, Map, String[])
storeAttrData(StringPartScan, Object, org.vishia.util.DataAccess.DatapathElement, Map, CharSequence, CharSequence, String)
inp
- scanOk-Position after the "<" before the identifier.output
- instance to store the parsed data.cfgNode
- The config for this elementjava.lang.Exception
private java.lang.String parseAttributes(StringPartScan inp, java.lang.String tag, XmlCfg.XmlCfgNode cfgNode, java.util.List<XmlJzReader.AttribToStore>[] attribsToStore, java.util.List<XmlJzReader.AttribToStore>[] namespacesToStore) throws java.lang.Exception
inp
- tag
- cfgNode
- attribsToStore
- [0] maybe given or may be created. If an attribute is found
which's XmlCfg.AttribDstCheck.daccess
is set, then the attribute with the daccess is stored in [0]
to write it in the new created node if this was created after this operation.namespacesToStore
- attribNames
- Reference to a map with key,name for attribute values.
The key is given in the config file, cfgNode.(XmlCfg.XmlCfgNode.attribs
) contains the association
it is not the attribute name anyway, but often the attribute name if the config file determines that.attribValues
- java.lang.Exception
private XmlCfg.AttribDstCheck getCfgAttrib(java.lang.CharSequence sAttrNsName, XmlCfg.XmlCfgNode cfgNode)
private void storeAttributesDueToSubCfgNode(XmlCfg.XmlCfgNode cfgNode, java.util.List<XmlJzReader.AttribToStore> attribStore, java.util.List<XmlJzReader.AttribToStore> namespacesStore, java.util.Map<java.lang.String,DataAccess.IntegerIx> attribNames, java.lang.String[] attribValues)
java.lang.Object getDataForTheElement(java.lang.Object output, DataAccess.DatapathElement elementStorePath, java.lang.String[] attribValues)
output
- The current output in the parent contextelementStorePath
- if null, returns output. Else: The storePath in the XmlCfg.XmlCfgNode
attribValues
- subCfgNode
- The cfgNode for the found elementsTag
- it is the keyResearch maybe assembled with attribute values, not only the tag name.DataAccess
or accessed datajava.lang.Exception
void finishElement(java.lang.Object parent, java.lang.Object element, DataAccess.DatapathElement elementStorePath)
parent
- The element where the content is to insert as sub content.element
- to insertelementStorePath
- rule where to insert: It contains:
DataAccess.DatapathElement#ident
Immediately the name of the variable of operation to call in parent
DataAccess.DatapathElement#args
Arguments, whereas the argument for finish should be usual "value",
which is the [1] element in the immediately argument list
for the internal called DataAccess.invokeMethod(org.vishia.util.DataAccess.DatapathElement, Class, Object, boolean, Object[], boolean)
for the "varValues".
private void storeAttrData(StringPartScan inp, java.lang.Object output, DataAccess.DatapathElement dstPath, java.util.Map<java.lang.String,DataAccess.IntegerIx> attribNames, java.lang.CharSequence sAttrName, java.lang.CharSequence sAttrValue, java.lang.String sTag)
output
- It is an instance of XmlCfgNode
while reading the cfg.xml, it is an user instance while reading the user.xmldstPath
- The dataAccess which should be executed.sAttrNsName
- sAttrValue
- private java.lang.CharSequence parseContent(StringPartScan inp, java.lang.StringBuilder buffer) throws java.io.IOException, java.text.ParseException
replaceSpecialCharsInText(CharSequence)
inp
- buffer
- maybe null then ignore content.java.text.ParseException
java.io.IOException
private static void storeContent(java.lang.StringBuilder buffer, XmlCfg.XmlCfgNode cfgNode, java.lang.Object output, DataAccess.DatapathElement contentStorePath, java.util.Map<java.lang.String,DataAccess.IntegerIx> attribs, java.lang.String[] attribValues)
private java.lang.CharSequence replaceSpecialCharsInText(java.lang.CharSequence src) throws java.text.ParseException
src
- java.text.ParseException
private void errMsg(int nr, StringPartScan inp, java.lang.CharSequence... txt)
public XmlCfg readCfg(java.io.File file) throws java.io.IOException
file
- from this filecfg
.
But you can store this reference and used for readXml(File, Object, XmlCfg)
later too.java.io.IOException
public void setCfg(XmlCfg cfg)
cfg
- public XmlCfg getCfg()
readCfg(File)
or readCfgFromJar(Class, String)
-as result from settingpublic XmlCfg readCfgFromJar(java.lang.Class<?> clazz, java.lang.String pathInJarFromClazz) throws java.io.IOException
clazz
- A class in any jar, from there the relative path to the pathInJar is built.
Often the clazz should be the output data clazz.pathInJar
- relative Path from clazz.
Usually the cfg should be in the same directory as the output data class. Then this is only the file name.cfg
.
But you can store this reference and used for readXml(File, Object, XmlCfg)
later too.java.io.IOException
public XmlCfg readCfgTxtFromJar(java.lang.Class<?> clazz, java.lang.String pathInJarFromClazz) throws java.io.IOException
clazz
- A class in any jar, from there the relative path to the pathInJar is built.
Often the clazz should be the output data clazz.pathInJar
- relative Path from clazz.
Usually the cfg should be in the same directory as the output data class. Then this is only the file name.cfg
.
But you can store this reference and used for readXml(File, Object, XmlCfg)
later too.java.io.IOException
public java.lang.String readXml(java.io.File file, java.lang.Object dst) throws java.io.IOException
java.io.IOException
public java.lang.String readXml(java.io.InputStream stream, java.lang.String sInputPath, java.lang.Object dst)
public java.lang.String readXml(java.io.Reader stream, java.lang.String sInputPath, java.lang.Object dst)