[#5853] Alternative record representations

This commit is contained in:
lukaseder 2017-02-09 23:28:47 +01:00
parent 95f9c12715
commit b08e191ea2
3 changed files with 111 additions and 23 deletions

View File

@ -41,11 +41,12 @@ package org.jooq;
*/
public final class XMLFormat {
final boolean xmlns;
final boolean format;
final String newline;
final int indent;
final boolean header;
final boolean xmlns;
final boolean format;
final String newline;
final int indent;
final boolean header;
final RecordFormat recordFormat;
public XMLFormat() {
this(
@ -53,7 +54,8 @@ public final class XMLFormat {
false,
"\n",
2,
true
true,
RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE
);
}
@ -62,13 +64,15 @@ public final class XMLFormat {
boolean format,
String newline,
int indent,
boolean header
boolean header,
RecordFormat recordFormat
) {
this.xmlns = xmlns;
this.format = format;
this.newline = newline;
this.indent = indent;
this.header = header;
this.recordFormat = recordFormat;
}
/**
@ -80,7 +84,8 @@ public final class XMLFormat {
format,
newline,
indent,
header
header,
recordFormat
);
}
@ -100,7 +105,8 @@ public final class XMLFormat {
newFormat,
newline,
indent,
header
header,
recordFormat
);
}
@ -120,7 +126,8 @@ public final class XMLFormat {
format,
newNewline,
indent,
header
header,
recordFormat
);
}
@ -140,7 +147,8 @@ public final class XMLFormat {
format,
newline,
newIndent,
header
header,
recordFormat
);
}
@ -163,7 +171,8 @@ public final class XMLFormat {
format,
newline,
indent,
newHeader
newHeader,
recordFormat
);
}
@ -173,4 +182,48 @@ public final class XMLFormat {
public boolean header() {
return header;
}
/**
* The record format to be applied, defaulting to
* {@link RecordFormat#VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE}.
*/
public XMLFormat recordFormat(RecordFormat newRecordFormat) {
return new XMLFormat(
xmlns,
format,
newline,
indent,
header,
newRecordFormat
);
}
/**
* The record format to be applied, defaulting to
* {@link RecordFormat#VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE}.
*/
public RecordFormat recordFormat() {
return recordFormat;
}
/**
* The format of individual XML records.
*/
public enum RecordFormat {
/**
* The default: <code>/record/value[@field="colname"]/text()</code>.
*/
VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE,
/**
* Simplified: <code>/record/value/text()</code>.
*/
VALUE_ELEMENTS,
/**
* Simplified: <code>/record/colname/text()</code>.
*/
COLUMN_NAME_ELEMENTS,
}
}

View File

@ -37,6 +37,8 @@ package org.jooq.impl;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.jooq.XMLFormat.RecordFormat.COLUMN_NAME_ELEMENTS;
import static org.jooq.XMLFormat.RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE;
import static org.jooq.impl.DSL.insertInto;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.table;
@ -1052,11 +1054,21 @@ final class ResultImpl<R extends Record> implements Result<R>, AttachableInterna
writer.append(newline).append(indent[recordLevel]).append("<record>");
for (int index = 0; index < fields.fields.length; index++) {
writer.append(newline).append(indent[valueLevel]);
String tag = format.recordFormat() == COLUMN_NAME_ELEMENTS
? escapeXML(fields.fields[index].getName())
: "value";
Object value = record.get(index);
writer.append(newline).append(indent[valueLevel]).append("<value field=\"");
writer.append(escapeXML(fields.fields[index].getName()));
writer.append("\"");
writer.append("<" + tag);
if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE) {
writer.append(" field=\"");
writer.append(escapeXML(fields.fields[index].getName()));
writer.append("\"");
}
if (value == null) {
writer.append("/>");
@ -1064,7 +1076,7 @@ final class ResultImpl<R extends Record> implements Result<R>, AttachableInterna
else {
writer.append(">");
writer.append(escapeXML(format0(value, false, false)));
writer.append("</value>");
writer.append("</" + tag + ">");
}
}
@ -1195,8 +1207,14 @@ final class ResultImpl<R extends Record> implements Result<R>, AttachableInterna
Field<?> field = fields.fields[index];
Object value = record.get(index);
Element eValue = document.createElement("value");
eValue.setAttribute("field", field.getName());
String tag = format.recordFormat() == COLUMN_NAME_ELEMENTS
? escapeXML(fields.fields[index].getName())
: "value";
Element eValue = document.createElement(tag);
if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE)
eValue.setAttribute("field", field.getName());
eRecord.appendChild(eValue);
if (value != null) {
@ -1265,17 +1283,23 @@ final class ResultImpl<R extends Record> implements Result<R>, AttachableInterna
Field<?> field = fields.fields[index];
Object value = record.get(index);
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", "", "field", "CDATA", field.getName());
String tag = format.recordFormat() == COLUMN_NAME_ELEMENTS
? escapeXML(fields.fields[index].getName())
: "value";
handler.startElement("", "", "value", attrs);
AttributesImpl attrs = new AttributesImpl();
if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE)
attrs.addAttribute("", "", "field", "CDATA", field.getName());
handler.startElement("", "", tag, attrs);
if (value != null) {
char[] chars = format0(value, false, false).toCharArray();
handler.characters(chars, 0, chars.length);
}
handler.endElement("", "", "value");
handler.endElement("", "", tag);
}
handler.endElement("", "", "record");

View File

@ -38,15 +38,26 @@
</complexType>
<complexType name="Record">
<!--
It is not possible, in XSD, to enforce a choice between a well defined type and a wildcard as below.
If, however, a <value/> element is present, then the following behaviour can be assumed:
- If there are only value elements, then the jooq-export:Value type is parsed
- If there is at least one non-value element, then the wildcard is parsed
<sequence>
<element name="value" type="jooq-export:Value" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
-->
<sequence>
<any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</sequence>
</complexType>
<complexType name="Value">
<simpleContent>
<extension base="string">
<attribute name="field" type="string"/>
<attribute name="field" type="string" use="optional"/>
</extension>
</simpleContent>
</complexType>