[jOOQ/jOOQ#19147] Result::formatXML should offer a way to configure NULL
encoding
This commit is contained in:
parent
b91b735808
commit
98d66c48ed
@ -64,6 +64,7 @@ public final class XMLFormat {
|
||||
boolean header;
|
||||
RecordFormat recordFormat;
|
||||
boolean quoteNested;
|
||||
NullFormat nullFormat;
|
||||
|
||||
public XMLFormat() {
|
||||
this(
|
||||
@ -76,7 +77,8 @@ public final class XMLFormat {
|
||||
null,
|
||||
true,
|
||||
RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE,
|
||||
false
|
||||
false,
|
||||
NullFormat.EMPTY_ELEMENT
|
||||
);
|
||||
}
|
||||
|
||||
@ -90,7 +92,8 @@ public final class XMLFormat {
|
||||
String[] indented,
|
||||
boolean header,
|
||||
RecordFormat recordFormat,
|
||||
boolean quoteNested
|
||||
boolean quoteNested,
|
||||
NullFormat nullFormat
|
||||
) {
|
||||
this.mutable = mutable;
|
||||
this.xmlns = xmlns;
|
||||
@ -107,6 +110,7 @@ public final class XMLFormat {
|
||||
this.header = header;
|
||||
this.recordFormat = recordFormat;
|
||||
this.quoteNested = quoteNested;
|
||||
this.nullFormat = nullFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,7 +136,8 @@ public final class XMLFormat {
|
||||
indented,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
else
|
||||
return this;
|
||||
@ -158,7 +163,8 @@ public final class XMLFormat {
|
||||
indented,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -189,7 +195,8 @@ public final class XMLFormat {
|
||||
null,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -220,7 +227,8 @@ public final class XMLFormat {
|
||||
indented,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -252,7 +260,8 @@ public final class XMLFormat {
|
||||
null,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -283,7 +292,8 @@ public final class XMLFormat {
|
||||
null,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -335,7 +345,8 @@ public final class XMLFormat {
|
||||
indented,
|
||||
newHeader,
|
||||
recordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -367,7 +378,8 @@ public final class XMLFormat {
|
||||
indented,
|
||||
header,
|
||||
newRecordFormat,
|
||||
quoteNested
|
||||
quoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -401,7 +413,8 @@ public final class XMLFormat {
|
||||
indented,
|
||||
header,
|
||||
recordFormat,
|
||||
newQuoteNested
|
||||
newQuoteNested,
|
||||
nullFormat
|
||||
);
|
||||
}
|
||||
|
||||
@ -413,6 +426,40 @@ public final class XMLFormat {
|
||||
return quoteNested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether nested {@link XML} content should be quoted like a string, or
|
||||
* nested into XML formatted output.
|
||||
*/
|
||||
@NotNull
|
||||
public final XMLFormat nullFormat(NullFormat newNullFormat) {
|
||||
if (mutable) {
|
||||
nullFormat = newNullFormat;
|
||||
return this;
|
||||
}
|
||||
else
|
||||
return new XMLFormat(
|
||||
mutable,
|
||||
xmlns,
|
||||
format,
|
||||
newline,
|
||||
globalIndent,
|
||||
indent,
|
||||
indented,
|
||||
header,
|
||||
recordFormat,
|
||||
quoteNested,
|
||||
newNullFormat
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether nested {@link XML} content should be quoted like a string, or
|
||||
* nested into XML formatted output.
|
||||
*/
|
||||
public final NullFormat nullFormat() {
|
||||
return nullFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* The format of individual XML records.
|
||||
*/
|
||||
@ -433,4 +480,25 @@ public final class XMLFormat {
|
||||
*/
|
||||
COLUMN_NAME_ELEMENTS,
|
||||
}
|
||||
|
||||
/**
|
||||
* The format of a <code>null</code> value.
|
||||
*/
|
||||
public enum NullFormat {
|
||||
|
||||
/**
|
||||
* A <code>null</code> value is represented by an empty tag.
|
||||
*/
|
||||
EMPTY_ELEMENT,
|
||||
|
||||
/**
|
||||
* A <code>null</code> value is represented by an absent tag.
|
||||
*/
|
||||
ABSENT_ELEMENT,
|
||||
|
||||
/**
|
||||
* A <code>null</code> value is represented by a <code>xsi:nil="true"</code> attribute.
|
||||
*/
|
||||
XSI_NIL
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,8 @@ import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static org.jooq.JSONFormat.NullFormat.ABSENT_ON_NULL;
|
||||
import static org.jooq.XMLFormat.NullFormat.ABSENT_ELEMENT;
|
||||
import static org.jooq.XMLFormat.NullFormat.XSI_NIL;
|
||||
import static org.jooq.XMLFormat.RecordFormat.COLUMN_NAME_ELEMENTS;
|
||||
import static org.jooq.XMLFormat.RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE;
|
||||
import static org.jooq.conf.SettingsTools.renderLocale;
|
||||
@ -892,32 +894,37 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
? escapeXML(fields.field(index).getName())
|
||||
: "value";
|
||||
|
||||
writer.append("<" + tag);
|
||||
if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE) {
|
||||
writer.append(" field=\"");
|
||||
writer.append(escapeXML(fields.field(index).getName()));
|
||||
writer.append("\"");
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
writer.append("/>");
|
||||
}
|
||||
else {
|
||||
writer.append(">");
|
||||
|
||||
if (value instanceof Formattable f) {
|
||||
writer.append(newline).append(format.indentString(recordLevel + 2));
|
||||
int previous = format.globalIndent();
|
||||
f.formatXML(writer, format.globalIndent(format.globalIndent() + format.indent() * (recordLevel + 2)));
|
||||
format.globalIndent(previous);
|
||||
writer.append(newline).append(format.indentString(recordLevel + 1));
|
||||
if (value != null || format.nullFormat() != ABSENT_ELEMENT) {
|
||||
writer.append("<" + tag);
|
||||
if (format.recordFormat() == VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE) {
|
||||
writer.append(" field=\"");
|
||||
writer.append(escapeXML(fields.field(index).getName()));
|
||||
writer.append("\"");
|
||||
}
|
||||
else if (value instanceof XML && !format.quoteNested())
|
||||
writer.append(((XML) value).data());
|
||||
else
|
||||
writer.append(escapeXML(format0(value, false, false)));
|
||||
|
||||
writer.append("</" + tag + ">");
|
||||
if (value == null) {
|
||||
if (format.nullFormat() == XSI_NIL)
|
||||
writer.append(" xsi:nil=\"true\"");
|
||||
|
||||
writer.append("/>");
|
||||
}
|
||||
else {
|
||||
writer.append(">");
|
||||
|
||||
if (value instanceof Formattable f) {
|
||||
writer.append(newline).append(format.indentString(recordLevel + 2));
|
||||
int previous = format.globalIndent();
|
||||
f.formatXML(writer, format.globalIndent(format.globalIndent() + format.indent() * (recordLevel + 2)));
|
||||
format.globalIndent(previous);
|
||||
writer.append(newline).append(format.indentString(recordLevel + 1));
|
||||
}
|
||||
else if (value instanceof XML && !format.quoteNested())
|
||||
writer.append(((XML) value).data());
|
||||
else
|
||||
writer.append(escapeXML(format0(value, false, false)));
|
||||
|
||||
writer.append("</" + tag + ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user