Package org.apache.derby.iapi.types
Class SqlXmlUtil
- java.lang.Object
-
- org.apache.derby.iapi.types.SqlXmlUtil
-
public class SqlXmlUtil extends java.lang.Object
This class contains "utility" methods that work with XML-specific objects that are only available if JAXP and/or Xalan are in the classpath. NOTE: This class is only compiled with JDK 1.4 and higher since the XML-related classes that it uses (JAXP and Xalan) are not part of earlier JDKs. Having a separate class for this functionality is beneficial for two reasons: 1. Allows us to allocate XML objects and compile an XML query expression a single time per statement, instead of having to do it for every row against which the query is evaluated. An instance of this class is created at compile time and then passed to the appropriate operator implementation method in XML.java. 2. By keeping all XML-specific references in this one class, we have a single "point of entry" to the XML objects--namely, the constructor for this class. Thus, if we always make sure to check for the required XML classes _before_ calling this class's constructor, we can detect early on whether some classes (ex. Xalan) are missing, and can throw a friendly error up front, instead of a ClassNotFoundException somewhere deeper in the execution codepath. The initial check for the required XML classes can be found in XML.checkXMLRequirements(). Note that we don't want to put references to XML-specific objects directly into XML.java because that class (XML.java) is instantiated anytime a table with an XML column is referenced. That would mean that if a user tried to select a non-XML column (ex. integer) from a table that had at least one XML column in it, the user would have to have JAXP and Xalan classes in his/her classpath--which we don't want. Instead, by keeping all XML-specific objects in this one class, and then only instantiating this class when an XML operator is used (either implicitly or explicitly), we make it so that the user is only required to have XML-specific classes in his/her classpath _if_ s/he is trying to access or operate on XML values.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
SqlXmlUtil.NullNamespaceContext
A NamespaceContext that reports all namespaces as unbound.private class
SqlXmlUtil.XMLErrorHandler
-
Field Summary
Fields Modifier and Type Field Description private javax.xml.parsers.DocumentBuilder
dBuilder
private javax.xml.xpath.XPathExpression
query
The compiled XPath query.private javax.xml.namespace.QName
returnType
The return type of the XPath query.private javax.xml.transform.Transformer
serializer
-
Constructor Summary
Constructors Constructor Description SqlXmlUtil()
Constructor: Initializes objects required for parsing and serializing XML values.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
compileXQExpr(java.lang.String queryExpr, java.lang.String opName)
Take the received string, which is an XML query expression, compile it, and store the compiled query locally.private java.lang.Object
evaluate(org.w3c.dom.Document doc)
Evaluate the XPath query on the specified document.protected java.util.List
evalXQExpression(XMLDataValue xmlContext, boolean returnResults, int[] resultXType)
Evaluate this object's compiled XML query expression against the received xmlContext.private void
loadSerializer()
Create an instance of Xalan serializer for the sake of serializing an XML value according the SQL/XML specification for serialization.protected java.lang.String
serializeToString(java.lang.String xmlAsText)
Take a string representing an XML value and serialize it according SQL/XML serialization rules.protected java.lang.String
serializeToString(java.util.List items, XMLDataValue xmlVal)
Take an array list (sequence) of XML nodes and/or string values and serialize that entire list according to SQL/XML serialization rules, which ultimately point to XML serialization rules as defined by w3c.
-
-
-
Field Detail
-
dBuilder
private javax.xml.parsers.DocumentBuilder dBuilder
-
serializer
private javax.xml.transform.Transformer serializer
-
query
private javax.xml.xpath.XPathExpression query
The compiled XPath query.
-
returnType
private javax.xml.namespace.QName returnType
The return type of the XPath query.null
if it is unknown.
-
-
Constructor Detail
-
SqlXmlUtil
public SqlXmlUtil() throws StandardException
Constructor: Initializes objects required for parsing and serializing XML values. Since most XML operations that require XML-specific classes perform both parsing and serialization at some point, we just initialize the objects up front.- Throws:
StandardException
-
-
Method Detail
-
compileXQExpr
public void compileXQExpr(java.lang.String queryExpr, java.lang.String opName) throws StandardException
Take the received string, which is an XML query expression, compile it, and store the compiled query locally. Note that for now, we only support XPath because that's what Xalan supports.- Parameters:
queryExpr
- The XPath expression to compile- Throws:
StandardException
-
serializeToString
protected java.lang.String serializeToString(java.lang.String xmlAsText) throws java.lang.Exception
Take a string representing an XML value and serialize it according SQL/XML serialization rules. Right now, we perform this serialization by first parsing the string into a JAXP Document object, and then applying the serialization semantics to that Document. That seems a bit inefficient, but neither Xalan nor JAXP provides a more direct way to do this.- Parameters:
xmlAsText
- String version of XML on which to perform serialization.- Returns:
- A properly serialized version of xmlAsText.
- Throws:
java.lang.Exception
-
serializeToString
protected java.lang.String serializeToString(java.util.List items, XMLDataValue xmlVal) throws javax.xml.transform.TransformerException
Take an array list (sequence) of XML nodes and/or string values and serialize that entire list according to SQL/XML serialization rules, which ultimately point to XML serialization rules as defined by w3c. As part of that serialization process we have to first "normalize" the sequence. We do that by iterating through the list and performing the steps for "sequence normalization" as defined here: http://www.w3.org/TR/xslt-xquery-serialization/#serdm This method primarily focuses on taking the steps for normalization; for the rest of the serialization work, we just make calls on the DOMSerializer class provided by Xalan.- Parameters:
items
- List of items to serialize. It should either be a list of a single string value (in case it's the result of an XMLQUERY operation that returns an atomic value), or a list of zero or more Node objects.xmlVal
- XMLDataValue into which the serialized string returned by this method is ultimately going to be stored. This is used for keeping track of XML values that represent sequences having top-level (parentless) attribute nodes.- Returns:
- Single string holding the serialized version of the normalized sequence created from the items in the received list.
- Throws:
javax.xml.transform.TransformerException
-
evalXQExpression
protected java.util.List evalXQExpression(XMLDataValue xmlContext, boolean returnResults, int[] resultXType) throws java.lang.Exception
Evaluate this object's compiled XML query expression against the received xmlContext. Then if returnResults is false, return an empty sequence (ArrayList) if evaluation yields at least one item and return null if evaluation yields zero items (the caller can then just check for null to see if the query returned any items). If returnResults is true, then return return a sequence (ArrayList) containing all items returned from evaluation of the expression. This array list can contain any combination of atomic values and XML nodes; it may also be empty. Assumption here is that the query expression has already been compiled and is stored in this.query.- Parameters:
xmlContext
- The XML value against which to evaluate the stored (compiled) query expressionreturnResults
- Whether or not to return the actual results of the queryresultXType
- The qualified XML type of the result of evaluating the expression, if returnResults is true. If the result is a sequence of exactly one Document node then this will be XML(DOCUMENT(ANY)); else it will be XML(SEQUENCE). If returnResults is false, this value is ignored.- Returns:
- If returnResults is false then return an empty ArrayList if evaluation returned at least one item and return null otherwise. If returnResults is true then return an array list containing all of the result items and return the qualified XML type via the resultXType parameter.
- Throws:
java.lang.Exception
- thrown on error (and turned into a StandardException by the caller).
-
evaluate
private java.lang.Object evaluate(org.w3c.dom.Document doc) throws javax.xml.xpath.XPathExpressionException
Evaluate the XPath query on the specified document.- Throws:
javax.xml.xpath.XPathExpressionException
-
loadSerializer
private void loadSerializer() throws javax.xml.transform.TransformerConfigurationException
Create an instance of Xalan serializer for the sake of serializing an XML value according the SQL/XML specification for serialization.- Throws:
javax.xml.transform.TransformerConfigurationException
-
-