in solr/core/src/java/org/apache/solr/handler/loader/XMLLoader.java [323:479]
protected SolrInputDocument readDoc(XMLStreamReader parser, boolean forgiveNameAttr)
throws XMLStreamException {
SolrInputDocument doc = new SolrInputDocument();
String attrName;
String attrVal;
for (int i = 0; i < parser.getAttributeCount(); i++) {
attrName = parser.getAttributeLocalName(i);
if ("boost".equals(attrName)) {
String message =
"Ignoring document boost: "
+ parser.getAttributeValue(i)
+ " as index-time boosts are not supported anymore";
if (WARNED_ABOUT_INDEX_TIME_BOOSTS.compareAndSet(false, true)) {
log.warn(message);
} else {
log.debug(message);
}
} else {
if (!(NAME.equals(attrName) && forgiveNameAttr)) {
log.warn("XML element <doc> has invalid XML attr: {}", attrName);
}
}
}
StringBuilder text = new StringBuilder();
String currentFieldName = null;
boolean isNull = false;
boolean isLabeledChildDoc = false;
String update = null;
Collection<SolrInputDocument> subDocs = null;
Map<String, Map<String, Object>> updateMap = null;
boolean complete = false;
while (!complete) {
int event = parser.next();
switch (event) {
// Add everything to the text
case XMLStreamConstants.SPACE:
case XMLStreamConstants.CDATA:
case XMLStreamConstants.CHARACTERS:
text.append(parser.getText());
break;
case XMLStreamConstants.END_ELEMENT:
if ("doc".equals(parser.getLocalName())) {
if (subDocs != null && !subDocs.isEmpty()) {
doc.addChildDocuments(subDocs);
subDocs = null;
}
complete = true;
break;
} else if ("field".equals(parser.getLocalName())) {
// should I warn in some text has been found too
Object v = isNull ? null : text.toString();
if (update != null) {
if (updateMap == null) updateMap = new HashMap<>();
Map<String, Object> extendedValues =
updateMap.computeIfAbsent(currentFieldName, k -> CollectionUtil.newHashMap(1));
Object val = extendedValues.get(update);
if (val == null) {
extendedValues.put(update, v);
} else {
// multiple val are present
if (val instanceof List) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) val;
list.add(v);
} else {
List<Object> values = new ArrayList<>();
values.add(val);
values.add(v);
extendedValues.put(update, values);
}
}
break;
}
if (!isLabeledChildDoc) {
// only add data if this is not a childDoc, since it was added already
doc.addField(currentFieldName, v);
} else {
// reset so next field is not treated as child doc
isLabeledChildDoc = false;
}
// field is over
currentFieldName = null;
}
break;
case XMLStreamConstants.START_ELEMENT:
text.setLength(0);
String localName = parser.getLocalName();
if ("doc".equals(localName)) {
if (currentFieldName != null) { // enclosed in <field>
// flag to prevent spaces after doc from being added
isLabeledChildDoc = true;
SolrInputDocument child = readDoc(parser);
if (doc.containsKey(currentFieldName)) {
doc.getField(currentFieldName).addValue(child);
} else {
final List<Object> list = new ArrayList<>(List.of(child));
doc.addField(currentFieldName, list);
}
} else {
final String subdocName = parser.getAttributeValue(null, NAME);
if (subdocName != null) { // <doc name=""> enclosed in <doc>
doc.addField(subdocName, readDoc(parser, true));
} else { // unnamed <doc> enclosed in <doc>
if (subDocs == null) {
subDocs = new ArrayList<>();
}
subDocs.add(readDoc(parser));
}
}
} else {
if (!"field".equals(localName)) {
String msg = "XML element <doc> has invalid XML child element: " + localName;
log.warn(msg);
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, msg);
}
update = null;
isNull = false;
for (int i = 0; i < parser.getAttributeCount(); i++) {
attrName = parser.getAttributeLocalName(i);
attrVal = parser.getAttributeValue(i);
if (NAME.equals(attrName)) {
currentFieldName = attrVal;
} else if ("boost".equals(attrName)) {
String message =
"Ignoring field boost: "
+ attrVal
+ " as index-time boosts are not supported anymore";
if (WARNED_ABOUT_INDEX_TIME_BOOSTS.compareAndSet(false, true)) {
log.warn(message);
} else {
log.debug(message);
}
} else if ("null".equals(attrName)) {
isNull = StrUtils.parseBoolean(attrVal);
} else if ("update".equals(attrName)) {
update = attrVal;
} else {
log.warn("XML element <field> has invalid XML attr: {}", attrName);
}
}
}
break;
}
}
if (updateMap != null) {
for (Map.Entry<String, Map<String, Object>> entry : updateMap.entrySet()) {
doc.addField(entry.getKey(), entry.getValue());
}
}
return doc;
}