[jOOQ/jOOQ#19233] SQLDataType.XML should be bound as XMLTYPE, not as
String in Oracle
This commit is contained in:
parent
16cd10a484
commit
eaa1d8c32d
@ -546,7 +546,9 @@ public final class XMLFormat {
|
||||
ABSENT_ELEMENT,
|
||||
|
||||
/**
|
||||
* A <code>null</code> value is represented by a <code>xsi:nil="true"</code> attribute.
|
||||
* A <code>null</code> value is represented by a
|
||||
* <code>xsi:nil="true"</code> attribute if {@link XMLFormat#xmlns()} is
|
||||
* set, or <code>nil="true"</code>, if it is not set.
|
||||
*/
|
||||
XSI_NIL
|
||||
}
|
||||
|
||||
@ -123,7 +123,8 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||
*/
|
||||
abstract class AbstractResult<R extends Record> extends AbstractFormattable implements FieldsTrait, Iterable<R> {
|
||||
|
||||
final AbstractRow<R> fields;
|
||||
private static final String XSI_SCHEMA = "http://www.w3.org/2001/XMLSchema-instance";
|
||||
final AbstractRow<R> fields;
|
||||
|
||||
AbstractResult(Configuration configuration, AbstractRow<R> row) {
|
||||
super(configuration);
|
||||
@ -804,7 +805,11 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
if (format.xmlns()) {
|
||||
format = format.xmlns(false);
|
||||
writer.append(" xmlns=\"" + Constants.NS_EXPORT + "\"");
|
||||
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
writer.append(" xsi:xmlns=\"" + XSI_SCHEMA + "\"");
|
||||
}
|
||||
|
||||
writer.append(">");
|
||||
|
||||
if (format.header()) {
|
||||
@ -878,6 +883,9 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
if (format.xmlns()) {
|
||||
format = format.xmlns(false);
|
||||
writer.append(" xmlns=\"" + Constants.NS_EXPORT + "\"");
|
||||
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
writer.append(" xsi:xmlns=\"" + XSI_SCHEMA + "\"");
|
||||
}
|
||||
|
||||
if (record == null) {
|
||||
@ -906,7 +914,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
if (value == null) {
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
writer.append(" xsi:nil=\"true\"");
|
||||
writer.append(" ").append(nil(format)).append("=\"true\"");
|
||||
|
||||
writer.append("/>");
|
||||
}
|
||||
@ -943,7 +951,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
if (o == null) {
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
writer.append(" xsi:nil=\"true\"");
|
||||
writer.append(" ").append(nil(format)).append("=\"true\"");
|
||||
|
||||
writer.append("/>");
|
||||
}
|
||||
@ -1233,11 +1241,12 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
Element eResult = document.createElement("result");
|
||||
|
||||
if (format.xmlns())
|
||||
if (format.xmlns()) {
|
||||
eResult.setAttribute("xmlns", Constants.NS_EXPORT);
|
||||
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
eResult.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
eResult.setAttribute("xmlns:xsi", XSI_SCHEMA);
|
||||
}
|
||||
|
||||
document.appendChild(eResult);
|
||||
|
||||
@ -1318,7 +1327,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
) {
|
||||
if (value == null) {
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
eParent.setAttribute("xsi:nil", "true");
|
||||
eParent.setAttribute(nil(format), "true");
|
||||
}
|
||||
else if (value instanceof Formattable f) {
|
||||
Document d = f.intoXML(format);
|
||||
@ -1338,7 +1347,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
if (o == null) {
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
eElement.setAttribute("xsi:nil", "true");
|
||||
eElement.setAttribute(nil(format), "true");
|
||||
}
|
||||
else
|
||||
intoXMLContent(format, builder, document, o, eElement);
|
||||
@ -1357,7 +1366,11 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
eParent.setTextContent(format0(value, false, false));
|
||||
}
|
||||
|
||||
private final Node childElement(Node n) {
|
||||
private static final String nil(XMLFormat format) {
|
||||
return format.xmlns() ? "xsi:nil" : "nil";
|
||||
}
|
||||
|
||||
private static final Node childElement(Node n) {
|
||||
NodeList l = n.getChildNodes();
|
||||
|
||||
for (int i = 0; i < l.getLength(); i++) {
|
||||
@ -1431,9 +1444,13 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
handler.startDocument();
|
||||
|
||||
if (format.xmlns())
|
||||
if (format.xmlns()) {
|
||||
handler.startPrefixMapping("", Constants.NS_EXPORT);
|
||||
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
handler.startPrefixMapping("xsi", XSI_SCHEMA);
|
||||
}
|
||||
|
||||
handler.startElement("", "", "result", empty);
|
||||
if (format.header()) {
|
||||
handler.startElement("", "", "fields", empty);
|
||||
@ -1501,8 +1518,12 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
if (format.header())
|
||||
handler.endElement("", "", "records");
|
||||
|
||||
if (format.xmlns())
|
||||
if (format.xmlns()) {
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
handler.endPrefixMapping("xsi");
|
||||
|
||||
handler.endPrefixMapping("");
|
||||
}
|
||||
|
||||
handler.endDocument();
|
||||
return handler;
|
||||
@ -1564,7 +1585,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
return formatted;
|
||||
}
|
||||
|
||||
private static final String escapeXML(String string) {
|
||||
static final String escapeXML(String string) {
|
||||
return StringUtils.replaceEach(string,
|
||||
new String[] { "\"", "'", "<", ">", "&" },
|
||||
new String[] { """, "'", "<", ">", "&"});
|
||||
|
||||
@ -107,6 +107,7 @@ import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.log;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.using;
|
||||
import static org.jooq.impl.DSL.xmlserializeContent;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.REQUIRES_LITERAL_CAST;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.infinity;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.nan;
|
||||
@ -146,11 +147,14 @@ import static org.jooq.impl.Keywords.K_TRUE;
|
||||
import static org.jooq.impl.Keywords.K_YEAR_TO_DAY;
|
||||
import static org.jooq.impl.Keywords.K_YEAR_TO_FRACTION;
|
||||
import static org.jooq.impl.Names.N_BYTEA;
|
||||
import static org.jooq.impl.Names.N_CREATEXML;
|
||||
import static org.jooq.impl.Names.N_HEX;
|
||||
import static org.jooq.impl.Names.N_JSON_PARSE;
|
||||
import static org.jooq.impl.Names.N_PARSE_JSON;
|
||||
import static org.jooq.impl.Names.N_ST_GEOMFROMTEXT;
|
||||
import static org.jooq.impl.Names.N_ST_GEOMFROMWKB;
|
||||
import static org.jooq.impl.Names.N_TO_BINARY;
|
||||
import static org.jooq.impl.Names.N_XMLTYPE;
|
||||
import static org.jooq.impl.R2DBC.isR2dbc;
|
||||
import static org.jooq.impl.SQLDataType.BIGINT;
|
||||
import static org.jooq.impl.SQLDataType.BLOB;
|
||||
@ -333,6 +337,8 @@ import org.jooq.types.YearToMonth;
|
||||
import org.jooq.types.YearToSecond;
|
||||
import org.jooq.util.postgres.PostgresUtils;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
// ...
|
||||
// ...
|
||||
|
||||
@ -934,6 +940,15 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (dataType.isUUID()) {
|
||||
switch (ctx.family()) {
|
||||
|
||||
@ -1220,7 +1235,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
private final void sql(BindingSQLContext<U> ctx, T value) throws SQLException {
|
||||
if (ctx.render().paramType() == INLINED)
|
||||
if (value == null)
|
||||
ctx.render().visit(K_NULL);
|
||||
sqlInlineNull0(ctx);
|
||||
else
|
||||
sqlInline0(ctx, value);
|
||||
else
|
||||
@ -1330,7 +1345,10 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
ctx.statement().registerOutParameter(ctx.index(), sqltype(ctx.statement(), ctx.configuration()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
/* non-final */ void sqlInlineNull0(BindingSQLContext<U> ctx) {
|
||||
ctx.render().visit(K_NULL);
|
||||
}
|
||||
|
||||
/* non-final */ void sqlInline0(BindingSQLContext<U> ctx, T value) throws SQLException {
|
||||
sqlInline1(ctx, value);
|
||||
}
|
||||
@ -6554,6 +6572,54 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
super(dataType, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
final void sqlInlineNull0(BindingSQLContext<U> ctx) {
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
super.sqlInlineNull0(ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final void sqlInline0(BindingSQLContext<U> ctx, XML value) throws SQLException {
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
super.sqlInline0(ctx, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final void sqlBind0(BindingSQLContext<U> ctx, XML value) throws SQLException {
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
super.sqlBind0(ctx, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final void setNull0(BindingSetStatementContext<U> ctx) throws SQLException {
|
||||
|
||||
|
||||
@ -628,6 +628,12 @@ final class Multiset<R extends Record> extends AbstractField<Result<R>> implemen
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -97,6 +97,7 @@ final class Names {
|
||||
static final Name N_COUNT_IF = systemName("count_if");
|
||||
static final Name N_covarPop = systemName("covarPop");
|
||||
static final Name N_covarSamp = systemName("covarSamp");
|
||||
static final Name N_CREATEXML = systemName("createxml");
|
||||
static final Name N_CUBE = systemName("cube");
|
||||
static final Name N_CURRENT_BIGDATETIME = systemName("current_bigdatetime");
|
||||
static final Name N_CURRENT_DATE = systemName("current_date");
|
||||
|
||||
@ -38,6 +38,8 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
// ...
|
||||
import static org.jooq.XML.xml;
|
||||
import static org.jooq.impl.AbstractResult.escapeXML;
|
||||
import static org.jooq.impl.DSL.field;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DefaultDataType.getDataType;
|
||||
@ -51,18 +53,21 @@ import static org.jooq.impl.Tools.row0;
|
||||
import static org.jooq.tools.StringUtils.defaultIfBlank;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.jooq.ContextConverter;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DataType;
|
||||
@ -71,22 +76,181 @@ import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
final class XMLHandler<R extends Record>
|
||||
extends
|
||||
DefaultHandler
|
||||
implements
|
||||
LexicalHandler
|
||||
{
|
||||
private static final JooqLogger log = JooqLogger.getLogger(XMLHandler.class);
|
||||
private static final boolean debug = false;
|
||||
private final DSLContext ctx;
|
||||
private final Deque<State<R>> states;
|
||||
private State<R> s;
|
||||
|
||||
static class XMLWriter extends DefaultHandler implements LexicalHandler {
|
||||
final StringWriter out;
|
||||
int level;
|
||||
String lastElement;
|
||||
String[] lastAttributes;
|
||||
boolean cdata;
|
||||
|
||||
XMLWriter() {
|
||||
out = new StringWriter();
|
||||
|
||||
// [#19229] TODO: StringWriter seems good enough for our test cases. Perhaps, switch to XMLStreamWriter, instead?
|
||||
}
|
||||
|
||||
private boolean flushLastElement(boolean end) {
|
||||
if (lastElement != null) {
|
||||
out.write('<');
|
||||
out.write(lastElement);
|
||||
|
||||
if (lastAttributes != null) {
|
||||
for (int i = 0; i < lastAttributes.length; i += 2) {
|
||||
out.write(' ');
|
||||
out.write(lastAttributes[i]);
|
||||
out.write("=\"");
|
||||
out.write(escapeXML(lastAttributes[i + 1]));
|
||||
out.write("\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (end)
|
||||
out.write("/>");
|
||||
else
|
||||
out.write('>');
|
||||
|
||||
lastElement = null;
|
||||
lastAttributes = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// ContentHandler API
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
|
||||
level++;
|
||||
|
||||
flushLastElement(false);
|
||||
lastElement = qName;
|
||||
|
||||
// [#19229] Attributes is a mutable object in some parsers (e.g. ojdbc ships its own),
|
||||
// so we have to copy its contents
|
||||
if (atts != null && atts.getLength() > 0) {
|
||||
lastAttributes = new String[atts.getLength() * 2];
|
||||
|
||||
for (int i = 0; i < atts.getLength(); i++) {
|
||||
lastAttributes[i * 2] = atts.getQName(i);
|
||||
lastAttributes[i * 2 + 1] = atts.getValue(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
if (!flushLastElement(true)) {
|
||||
out.write("</");
|
||||
out.write(qName);
|
||||
out.write('>');
|
||||
}
|
||||
|
||||
level--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processingInstruction(String target, String data) throws SAXException {
|
||||
flushLastElement(false);
|
||||
out.write("<?");
|
||||
out.write(target);
|
||||
|
||||
if (!StringUtils.isEmpty(data)) {
|
||||
out.write(' ');
|
||||
out.write(data);
|
||||
}
|
||||
|
||||
out.write("?>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
flushLastElement(false);
|
||||
|
||||
if (cdata)
|
||||
out.write(ch, start, length);
|
||||
else
|
||||
out.write(escapeXML(new String(ch, start, length)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||
flushLastElement(false);
|
||||
out.write(ch, start, length);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// LexicalHandler API
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void startCDATA() throws SAXException {
|
||||
cdata = true;
|
||||
flushLastElement(false);
|
||||
out.write("<![CDATA[");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endCDATA() throws SAXException {
|
||||
flushLastElement(false);
|
||||
out.write("]]>");
|
||||
cdata = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(char[] ch, int start, int length) throws SAXException {
|
||||
flushLastElement(false);
|
||||
|
||||
out.write("<!--");
|
||||
out.write(ch, start, length);
|
||||
out.write("-->");
|
||||
}
|
||||
|
||||
// [#19229] TODO: Implement these if needed
|
||||
|
||||
@Override
|
||||
public void startDTD(String name, String publicId, String systemId) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDTD() throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startEntity(String name) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endEntity(String name) throws SAXException {
|
||||
}
|
||||
}
|
||||
|
||||
private static class State<R extends Record> {
|
||||
final DSLContext ctx;
|
||||
AbstractRow<R> row;
|
||||
@ -101,6 +265,7 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
final List<Object> values;
|
||||
List<Object> elements;
|
||||
int column;
|
||||
XMLWriter writer;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
State(DSLContext ctx, AbstractRow<R> row, Class<? extends R> recordType) {
|
||||
@ -187,6 +352,11 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
// TODO: Why does the SAXParser replace \r by \n?
|
||||
|
||||
try {
|
||||
saxParser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
|
||||
}
|
||||
catch (SAXNotRecognizedException | SAXNotSupportedException ignore) {}
|
||||
|
||||
saxParser.parse(new ByteArrayInputStream(string.getBytes(ctx.configuration().charsetProvider().provide())), this);
|
||||
return s.result;
|
||||
}
|
||||
@ -202,7 +372,10 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("> " + qName);
|
||||
|
||||
if (!s.inResult && "result".equalsIgnoreCase(qName)) {
|
||||
if (s.writer != null) {
|
||||
s.writer.startElement(uri, localName, qName, attributes);
|
||||
}
|
||||
else if (!s.inResult && "result".equalsIgnoreCase(qName)) {
|
||||
s.inResult = true;
|
||||
}
|
||||
else if (s.inColumn && "result".equalsIgnoreCase(qName)) {
|
||||
@ -265,15 +438,23 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
|
||||
s.inColumn = true;
|
||||
|
||||
DataType<?> t = s.fields.get(s.column).getDataType();
|
||||
Field<?> f = s.fields.get(s.column);
|
||||
DataType<?> t = f.getDataType();
|
||||
|
||||
// [#13181] String NULL and '' values cannot be distinguished without xsi:nil
|
||||
if (t.isString() && !isNil(attributes))
|
||||
if (t.isString() && !isNil(attributes)) {
|
||||
s.values.add("");
|
||||
else if (t.isArray() && !isNil(attributes))
|
||||
}
|
||||
else if (t.isArray() && !isNil(attributes)) {
|
||||
s.elements = new ArrayList<>();
|
||||
else if (!t.isMultiset() && !t.isRecord())
|
||||
}
|
||||
else if (!t.isMultiset() && !t.isRecord()) {
|
||||
s.values.add(null);
|
||||
|
||||
// [#19229] Copy XML content
|
||||
if (f.getDataType().isXML() && s.writer == null)
|
||||
s.writer = new XMLWriter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +472,18 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("< " + qName);
|
||||
|
||||
if (states.isEmpty() && s.inResult && s.inRecord == 0 && "result".equalsIgnoreCase(qName)) {
|
||||
if (s.writer != null && s.writer.level == 0)
|
||||
s.writer = null;
|
||||
|
||||
if (s.writer != null) {
|
||||
s.writer.endElement(uri, localName, qName);
|
||||
|
||||
if (s.writer.level == 0) {
|
||||
s.values.set(s.values.size() - 1, xml(s.writer.out.toString()));
|
||||
s.writer = null;
|
||||
}
|
||||
}
|
||||
else if (states.isEmpty() && s.inResult && s.inRecord == 0 && "result".equalsIgnoreCase(qName)) {
|
||||
if (s.result == null)
|
||||
initResult();
|
||||
|
||||
@ -367,11 +559,20 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
return allMatch(fields, f -> "value".equalsIgnoreCase(f.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||
if (s.writer != null)
|
||||
s.writer.ignorableWhitespace(ch, start, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void characters(char[] ch, int start, int length) throws SAXException {
|
||||
DataType<?> t;
|
||||
|
||||
if (s.inColumn
|
||||
if (s.writer != null) {
|
||||
s.writer.characters(ch, start, length);
|
||||
}
|
||||
else if (s.inColumn
|
||||
&& !(t = s.fields.get(s.column).getDataType()).isRecord()
|
||||
&& !t.isMultiset()
|
||||
&& (!t.isArray() || s.inElement)
|
||||
@ -390,4 +591,46 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
|
||||
s.values.set(s.column, old + value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDTD(String name, String publicId, String systemId) throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.startDTD(name, publicId, systemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDTD() throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.endDTD();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startEntity(String name) throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.startEntity(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endEntity(String name) throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.endEntity(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startCDATA() throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.startCDATA();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endCDATA() throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.endCDATA();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(char[] ch, int start, int length) throws SAXException {
|
||||
if (s != null && s.writer != null)
|
||||
s.writer.comment(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user