Class 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.
    • 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.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 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 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:
        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