Class SqlXmlUtil

java.lang.Object
org.apache.derby.iapi.types.SqlXmlUtil

public class SqlXmlUtil extends 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.
  • Field Details

    • dBuilder

      private DocumentBuilder dBuilder
    • serializer

      private Transformer serializer
    • query

      private XPathExpression query
      The compiled XPath query.
    • returnType

      private QName returnType
      The return type of the XPath query. null if it is unknown.
  • Constructor Details

    • 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 Details

    • compileXQExpr

      public void compileXQExpr(String queryExpr, 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 String serializeToString(String xmlAsText) throws 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:
      Exception
    • serializeToString

      protected String serializeToString(List items, XMLDataValue xmlVal) throws 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:
      TransformerException
    • evalXQExpression

      protected List evalXQExpression(XMLDataValue xmlContext, boolean returnResults, int[] resultXType) throws 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 expression
      returnResults - Whether or not to return the actual results of the query
      resultXType - 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:
      Exception - thrown on error (and turned into a StandardException by the caller).
    • evaluate

      private Object evaluate(Document doc) throws XPathExpressionException
      Evaluate the XPath query on the specified document.
      Throws:
      XPathExpressionException
    • loadSerializer

      private void loadSerializer() throws TransformerConfigurationException
      Create an instance of Xalan serializer for the sake of serializing an XML value according the SQL/XML specification for serialization.
      Throws:
      TransformerConfigurationException