package org.exist.xquery.util; import org.exist.Namespaces; import org.exist.xquery.ErrorCodes; import org.exist.xquery.Expression; import org.exist.xquery.XPathException; import org.exist.xquery.functions.fn.FnModule; import org.exist.xquery.value.NodeValue; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import java.io.IOException; import java.util.Properties; /** * Serializer utilities used by several XQuery functions. */ public class SerializerUtils { /** * Parse output:serialization-parameters XML fragment into serialization * properties as defined by the fn:serialize function. * * @param parent the parent expression calling this method * @param parameters root node of the XML fragment * @param properties parameters are added to the given properties */ public static void getSerializationOptions(Expression parent, NodeValue parameters, Properties properties) throws XPathException { try { final XMLStreamReader reader = parent.getContext().getXMLStreamReader(parameters); while (reader.hasNext() && (reader.next() != XMLStreamReader.START_ELEMENT)) { } if (!reader.getNamespaceURI().equals(Namespaces.XSLT_XQUERY_SERIALIZATION_NS)) { throw new XPathException(parent, FnModule.SENR0001, "serialization parameter elements should be in the output namespace"); } while (reader.hasNext()) { final int status = reader.next(); if (status == XMLStreamReader.START_ELEMENT) { final String key = reader.getLocalName(); if (properties.contains(key)) {throw new XPathException(parent, FnModule.SEPM0019, "serialization parameter specified twice: " + key);} String value = reader.getAttributeValue("", "value"); if (value == null) { // backwards compatibility: use element text as value value = reader.getElementText(); } properties.put(key, value); } } } catch (final XMLStreamException | IOException e) { throw new XPathException(parent, ErrorCodes.EXXQDY0001, e.getMessage()); } } }