home *** CD-ROM | disk | FTP | other *** search
/ Dynamic HTML in Action / Dynamicke-HTML-v-akci-covermount.bin / XML / PARSER / XMLINST.EXE / classes / com / ms / xml / om / ElementImpl.java < prev    next >
Encoding:
Java Source  |  1998-05-22  |  23.7 KB  |  779 lines

  1. /*
  2.  * @(#)ElementImpl.java 1.0 6/3/97
  3.  * 
  4.  * Copyright (c) 1997 Microsoft, Corp. All Rights Reserved.
  5.  * 
  6.  */
  7.  
  8. package com.ms.xml.om;
  9.  
  10. import com.ms.xml.util.Attribute;
  11. import com.ms.xml.util.Attributes;
  12. import com.ms.xml.util.Name;
  13. import com.ms.xml.util.Atom;
  14. import com.ms.xml.util.XMLOutputStream;
  15. import com.ms.xml.util.EnumWrapper;
  16. import com.ms.xml.parser.ElementDecl;
  17. import com.ms.xml.parser.AttDef;
  18. import com.ms.xml.parser.DTD;
  19.  
  20. import java.io.IOException;
  21. import java.lang.String;
  22. import java.util.Vector;
  23. import java.util.Enumeration;
  24.  
  25. /**
  26.  * This class represents the default implementation of the <code>Element</code> interface. 
  27.  * These are 
  28.  * created by the XML parser when using the default element factory. 
  29.  * @see Element
  30.  * @see Parser
  31.  * @see ElementFactory
  32.  * @see ElementFactoryImpl
  33.  *
  34.  * @version 1.0, 6/3/97
  35.  */
  36. public class ElementImpl implements Element
  37. {
  38.     public ElementImpl()
  39.     {
  40.         this(null, Element.ELEMENT);
  41.     }
  42.     
  43.     public ElementImpl(Name tag, int type)
  44.     {
  45.         this.tag = tag;
  46.         this.type = type;
  47.     }
  48.  
  49.     /** 
  50.      * Retrieves the name of the tag as a string. The string
  51.      * will be in uppercase.
  52.      * 
  53.      * @return the tag name or null for DATA and PCDATA elements. 
  54.      
  55.      */
  56.     public Name getTagName()
  57.     {
  58.         return tag;
  59.     }
  60.  
  61.     /**
  62.      * Retrieves the type of the element.
  63.      * This is always one of the following values:
  64.      * <code>DOCUMENT</code>, <code>ELEMENT</code>, <code>PCDATA</code>, <code>PI</code>,
  65.      * <code>META</code>, <code>COMMENT</code>, or <code>CDATA</code>.
  66.      * 
  67.      * @return the element type.
  68.      */    
  69.     public int getType()
  70.     {
  71.         return type;
  72.     }
  73.  
  74.      /** 
  75.      * Returns the non-marked-up text contained by this element.
  76.      * For text elements, this is the raw data. For elements
  77.      * with child nodes, this method traverses the entire subtree and
  78.      * appends the text for each terminal text element, effectively
  79.      * stripping out the XML markup for the subtree. For example,
  80.      * if the XML document contains the following:
  81.      * <xmp>
  82.      *      <AUTHOR>
  83.      *          <FIRST>William</FIRST>
  84.      *          <LAST>Shakespeare</LAST>
  85.      *      </AUTHOR>
  86.      * </xmp>
  87.      * <p><code>Document.getText</code> returns "William Shakespeare".
  88.      */
  89.     public String getText()
  90.     {
  91.         if (type == ENTITYREF)
  92.         {
  93.             Document d = getDocument();
  94.             if (d != null)
  95.             {
  96.                 DTD dtd = d.getDTD();
  97.                 if (dtd != null) 
  98.                 {
  99.                     Element ent = dtd.findEntity(getTagName());
  100.                     if (ent != null) 
  101.                     {
  102.                         return ent.getText();
  103.                     }
  104.                 }
  105.             }
  106.         }
  107.         else if (children == null || type == CDATA || type == PCDATA || type == WHITESPACE)
  108.         {
  109.             return text == null ? new String("") : text;
  110.         }
  111.         else if (children != null)
  112.         {
  113.             StringBuffer sb = new StringBuffer();
  114.  
  115.             for (Enumeration en = children.elements(); en.hasMoreElements(); )
  116.             {
  117.                 sb.append(((Element)en.nextElement()).getText());
  118.             }
  119.  
  120.             return sb.toString();
  121.         }
  122.         
  123.         return "";
  124.     }
  125.     
  126.     /**
  127.      * Sets the text for this element. This text is Only meaningful in 
  128.      * <code>CDATA</code>, <code>PCDATA</code>, and <code>COMMENT</code> nodes.
  129.      *
  130.      * @param The text to set.
  131.      */    
  132.     public void setText(String text)
  133.     {
  134.         // No restrictions here, so that subclasses can use this.
  135.         this.text = text;
  136.     }
  137.  
  138.     /** 
  139.      * Retrieves the parent of this element. 
  140.      * Every element in the tree except the Document object  itself, has
  141.      * a parent.  
  142.      *
  143.      * @return the parent element or null if  the element is at the root of 
  144.      * the tree.
  145.      */
  146.     public Element getParent()
  147.     {
  148.         return parent;
  149.     }
  150.  
  151.     /**
  152.      * Sets the parent of this element.
  153.      * @param parent The element to set as the parent.
  154.       * @return No return value.
  155.      */
  156.     public void setParent(Element parent)
  157.     {
  158.         this.parent = parent;
  159.         doc = null; // reset cached doc pointer.
  160.     }
  161.  
  162.     /**
  163.      * Returns an enumeration of the children of this element.
  164.      * <code>Enumeration.nextElement</code> returns <code>Element</code> objects.
  165.      * 
  166.      * @return an enumeration of child objects. It must not return null. 
  167.      * See <code>EnumWrapper<code> for an easy way to return an empty enumeration.
  168.      */
  169.     public Enumeration getElements()
  170.     {
  171.         if (children == null) return EnumWrapper.emptyEnumeration;
  172.         return children.elements();
  173.     }
  174.  
  175.     /**
  176.      * Returns an element collection of the children of this element.
  177.      * This method must not return null. 
  178.      * See <code>EnumWrapper</code> for an empty enumeration. 
  179.      
  180.      * @return element collection of child objects. 
  181.      
  182.      */
  183.     public ElementCollection getChildren()
  184.     {
  185.         return new ElementCollection(this);
  186.     }
  187.  
  188.     /**
  189.      * Retrieves the number of attributes.
  190.      * @return the number of attributes.
  191.      */
  192.     public int numAttributes()
  193.     {
  194.         return (attrlist == null) ? 0 : attrlist.size();
  195.     }
  196.  
  197.     /**
  198.      * Retrieves the number of child elements.
  199.      * @return the number of child elements.
  200.      */
  201.     public int numElements()
  202.     {
  203.         return (children == null) ? 0 : children.size();
  204.     }
  205.  
  206.     /**
  207.      * Adds a child to this element. Any element can only
  208.      * have one parent element, and so the previous parent will lose this child
  209.      * from its subtree.  
  210.      
  211.      * @param elem  The element to add.      
  212.      * The child element becomes the last element if <i>after</i> is null.
  213.      * The child is added to the beginning of the list if <i>after</i> is this object.
  214.      * @param after  The element after which to add it.
  215.       * @return No return value.
  216.      */
  217.     public void addChild(Element elem, Element after)
  218.     {
  219.         if (children == null)
  220.         {
  221.             children = new Vector(4);
  222.         }
  223.         if (after == null)
  224.         {
  225.             children.addElement(elem);
  226.         }
  227.         else if (after == this)
  228.         {
  229.             children.insertElementAt(elem, 0);
  230.         }
  231.         else
  232.         {
  233.             children.insertElementAt(elem, children.indexOf(after) + 1);
  234.         }
  235.         elem.setParent(this);
  236.     }
  237.  
  238.     /**
  239.      * Adds a child to this element. 
  240.      * @param elem The element to add.
  241.      * @param pos  The position to add this element (calling <code>getChild(pos)</code> 
  242.      * will return this element). If <i>pos</i> is less than 0, <i>elem</i> becomes 
  243.      * the new last element.
  244.      * @param reserved The reserved parameter.
  245.       * @return No return value.
  246.      */
  247.     public void addChild(Element elem, int pos, int reserved)
  248.     {
  249.         if (pos == 0)
  250.             addChild(elem, this);
  251.         else if (pos < 0 || pos > numElements()-1)
  252.             addChild(elem, null);
  253.         else
  254.             addChild(elem, getChild(pos-1));
  255.     }
  256.  
  257.      /**
  258.       * Retrieves the child element by index.
  259.       * @param index The index of the child element.
  260.       * @return null if there is no child by that index.
  261.       */   
  262.     public Element getChild(int index)
  263.     {
  264.         if (children != null && index >= 0 && index < children.size()) 
  265.         {
  266.             try {
  267.                 return (Element)children.elementAt(index);
  268.             } catch (Exception e) {
  269.             }
  270.         }
  271.         return null;
  272.     }
  273.  
  274.      /**
  275.       * Removes a child element from the tree.
  276.       * @return No return value.
  277.       * @param elem  The element to remove.
  278.       */   
  279.     public void removeChild(Element elem)
  280.     {
  281.         if (children != null)
  282.         {
  283.             elem.setParent(null);
  284.             children.removeElement(elem);
  285.         }
  286.     }
  287.     
  288.     /**
  289.      * Retrieves an enumeration for the element attributes.
  290.      * 
  291.      * The enumeration returns <code>Attribute</code> objects.
  292.      * @return the enumeration. 
  293.      * This method must not return null (see <code>EnumWrapper</code>
  294.      * for returning empty enumerations).
  295.      * @see Attribute
  296.      */
  297.     public Enumeration getAttributes()
  298.     {
  299.         if (attrlist == null) return EnumWrapper.emptyEnumeration;
  300.         return attrlist.attributes();
  301.     }
  302.  
  303.     /**
  304.      * Retrieves an attribute's value given its name.
  305.      * @param name The name of the attribute.
  306.      * @return the value of the attribute; returns 
  307.      * null if the attribute is not found.
  308.      */    
  309.     public Object getAttribute(String name)
  310.     {
  311.         return getAttribute(qualifyName(name));
  312.     }
  313.  
  314.     /**
  315.      * Retrieves an attribute's value given its name.
  316.      * @param name The name of the attribute.
  317.      * @return the value of the attribute; returns 
  318.      * null if the attribute is not found.
  319.      */    
  320.     public Object getAttribute(Name attrName)
  321.     {
  322.         Object obj = null;
  323.         if (attrlist != null)
  324.         {
  325.             obj = attrlist.get(attrName);
  326.         }
  327.         return obj;
  328.     }
  329.     
  330.     /**
  331.      * Sets the attribute of this element.    
  332.      *
  333.      * @param name  The attribute name.
  334.      * @param value The attribute value.
  335.      * @return any previous value, if any.
  336.      */    
  337.     public void setAttribute(String name, Object value)
  338.     {
  339.         setAttribute(qualifyName(name), value);
  340.     }
  341.  
  342.     /**
  343.      * Deletes an attribute from an element.
  344.      * @param name The attribute to delete.
  345.       * @return No return value.
  346.      */    
  347.     public void removeAttribute(String name)
  348.     {
  349.         removeAttribute(qualifyName(name));
  350.     }
  351.     
  352.     /**
  353.      * Deletes an attribute from an element.
  354.      * @param attrName The attribute name to delete. 
  355.      */    
  356.     public void removeAttribute(Name attrName)
  357.     {
  358.         if (attrlist != null)
  359.         {
  360.             attrlist.remove(attrName);
  361.         }
  362.     }
  363.     
  364.     /**
  365.      * Retrieves the string representation of this element.
  366.      * @return a string representing the element.
  367.      */
  368.     public String toString()
  369.     {
  370.         return getClass().getName() + "[tag=" + tag + 
  371.             ",type=" + type + 
  372.             ",text=" + text + "]";
  373.     }
  374.  
  375.     /**
  376.      * Sets the attribute of this element.    
  377.      *
  378.      * @param attrName The attribute name. 
  379.      * @param value The attribute value.
  380.      */    
  381.     public void setAttribute(Name attrName, Object value)
  382.     {
  383.         if (attrlist == null)
  384.         {
  385.             attrlist = new Attributes();
  386.         }
  387.         attrlist.put(attrName, value);
  388.     }
  389.     
  390.     /**
  391.      * Removes child nodes and attributes.
  392.      */
  393.     void clear()
  394.     {
  395.         if (children != null)
  396.             children.removeAllElements();
  397.         text = null;
  398.         parent = null;
  399.         if (attrlist != null)
  400.             attrlist.removeAll(); 
  401.     }
  402.  
  403.     /**
  404.      * Save the element attributes in XML format
  405.      */
  406.     public void saveAttributes(Atom ns, XMLOutputStream o) throws IOException
  407.     {
  408.         for (Enumeration en = getAttributes(); en.hasMoreElements(); ) 
  409.         {
  410.             Attribute a = (Attribute)en.nextElement();
  411.             Name n = a.getName();
  412.             o.write(' ');
  413.             if (n == nameXMLSPACE)
  414.                 o.writeChars(n.getName());
  415.             else
  416.                 o.writeQualifiedName(n, ns);
  417.             o.write('=');
  418.             boolean qualified = isAttributeQualified(n,o.dtd);
  419.             Object attr = a.getValue();
  420.             if (attr instanceof Name)
  421.             {
  422.                 o.write('\"');
  423.                 if (qualified)
  424.                     o.writeQualifiedName((Name)attr, ns);
  425.                 else
  426.                     o.writeChars(attr.toString());
  427.                 o.write('\"');
  428.             }
  429.             else if (attr instanceof Vector)
  430.             {
  431.                 Vector v = (Vector)attr;
  432.                 o.write('\"');
  433.                 for (Enumeration av = v.elements(); av.hasMoreElements();)
  434.                 {
  435.                     Name avn = (Name)av.nextElement();                    
  436.                     if (qualified)
  437.                         o.writeQualifiedName(avn, ns);
  438.                     else
  439.                         o.writeChars(avn.toString());
  440.                     if (av.hasMoreElements())
  441.                         o.write(' ');    
  442.                 }
  443.                 o.write('\"');
  444.             }
  445.             else
  446.                 o.writeQuotedString(attr.toString());
  447.         }
  448.     }
  449.  
  450.     /**
  451.     * Determines if the attribute is qualified. 
  452.      * @param attr The name of the attribute.
  453.      * @param dtd The Document Definition Type (DTD) in which the attribute 
  454.      * is found.
  455.      * @return true if the attribute is qualified; otherwise, returns false.
  456.       * 
  457.      */
  458.     public boolean isAttributeQualified(Name attr, DTD dtd)
  459.     {
  460.         if (dtd != null) {
  461.             ElementDecl ed = dtd.findElementDecl(tag);
  462.             if (ed != null) {
  463.                 AttDef ad = ed.findAttDef(attr);
  464.                 if (ad != null) {
  465.                     int t = ad.getType();
  466.                     if (t == AttDef.ENTITY ||
  467.                         t == AttDef.ENTITIES ||
  468.                         t == AttDef.NOTATION)
  469.                     {
  470.                         return true;
  471.                     }
  472.                 }
  473.             }
  474.         }
  475.         return false;
  476.     }
  477.  
  478.     /**
  479.      * Returns the XML-DATA specification for the DTD element.
  480.      * (Only applies to ElementDecl and Entity nodes).
  481.      * This is DTD information represented in an XML Object Model.
  482.      * See <a href="http://www.microsoft.com/standards/xml/xmldata.htm">Specification for XML-Data</a> for details.
  483.      */
  484.     public Element toSchema()
  485.     {
  486.         return this;
  487.     }
  488.  
  489.  
  490.     /**
  491.      * Writes tag name
  492.      */
  493.     void writeTagName(XMLOutputStream o) throws IOException
  494.     {
  495.         Element parent = getParent();
  496.         Name tagName = getTagName();
  497.         if (parent != null && parent.getTagName() != null && parent.getTagName().getNameSpace() != null) {
  498.             o.writeQualifiedName(tagName, parent.getTagName().getNameSpace());
  499.         } else if (tagName.getNameSpace() != null) {
  500.             o.writeQualifiedName(tagName, Atom.create(""));
  501.         } else {
  502.             o.writeChars(tagName.getName());
  503.         }
  504.     }
  505.  
  506.     /**
  507.      * Saves the element in XML format.
  508.      * @param o The output stream to save to.
  509.      * @exception IOException if an error occurs when writing to the output 
  510.      * stream.
  511.      * @return No return value.
  512.      */
  513.     public void save(XMLOutputStream o) throws IOException
  514.     {
  515.         if (getType() != WHITESPACE)
  516.             o.writeIndent();
  517.         int type = getType();
  518.         switch (type)
  519.         {
  520.             case Element.WHITESPACE:
  521.                 if (o.getOutputStyle() == XMLOutputStream.DEFAULT)
  522.                     o.writeChars(getText());
  523.                 break;
  524.             case Element.ELEMENT:
  525.             case Element.ENTITY: // in schema format
  526.                 {
  527.                     int oldStyle = -1;
  528.                     boolean wasmixed = o.mixed;
  529.                     if (tag != null) 
  530.                     {
  531.                         o.writeChars("<");
  532.                         // Write out the tag name
  533.                         writeTagName(o);
  534.                         // Write out the attributes.
  535.                         saveAttributes(getTagName().getNameSpace(), o);
  536.                         // Find out if we're preserving white space.
  537.                         Object v = getAttribute(nameXMLSPACE);
  538.                         String value = null;
  539.                         if (v != null) value = v.toString();
  540.                         if (value != null) 
  541.                         {
  542.                             oldStyle = o.getOutputStyle();
  543.                             boolean preserveWS = value.equalsIgnoreCase("preserve");
  544.                             o.setOutputStyle(preserveWS ? XMLOutputStream.COMPACT : 
  545.                                 XMLOutputStream.PRETTY);
  546.                         }    
  547.                         // Write the close start tag.
  548.                         if (numElements() > 0)
  549.                         {
  550.                             o.write('>');                            
  551.                         }
  552.                         else
  553.                         {
  554.                             o.writeChars("/>");
  555.                         }                                                
  556.                     }
  557.                     // find out if this is a mixed element.
  558.                     ElementEnumeration ee = null;
  559.                     o.mixed = false; // not inherited down heirarchy.
  560.                     for (ee = new ElementEnumeration(this); ee.hasMoreElements(); )
  561.                     {
  562.                         Element ne = (Element)ee.nextElement();
  563.                         if (ne.getType() == PCDATA || ne.getType() == ENTITYREF)
  564.                         {
  565.                             o.mixed = true;
  566.                             break;
  567.                         }
  568.                     }
  569.                     o.writeNewLine();
  570.                     o.addIndent(1);
  571.                     o.nameSpaceContext.push();
  572.                     for (ee = new ElementEnumeration(this); ee.hasMoreElements(); )
  573.                     {
  574.                         Element ne = (Element)ee.nextElement();
  575.                         ne.save(o);
  576.                     }
  577.                     o.nameSpaceContext.pop();
  578.                     o.addIndent(-1);
  579.                     if (tag != null && numElements() > 0) 
  580.                     {                        
  581.                         o.writeIndent();
  582.                         o.writeChars("</");
  583.                         writeTagName(o);
  584.                         o.writeChars(">");
  585.                         if (oldStyle != -1) 
  586.                         {
  587.                             o.setOutputStyle(oldStyle);
  588.                         }
  589.                         o.mixed = wasmixed;
  590.                         o.writeNewLine();
  591.                     }
  592.                 }
  593.                 break;
  594.             case Element.PI:
  595.                 o.writeChars("<?");
  596.                 o.writeQualifiedName(getTagName(), null);
  597.                 saveAttributes(getTagName().getNameSpace(), o);
  598.                 o.writeChars(getText() + "?>");
  599.                 o.writeNewLine();
  600.                 break;
  601.             case Element.CDATA:
  602.                 o.writeChars("<![CDATA[" + getText() + "]]>");
  603.                 o.writeNewLine();
  604.                 break;
  605.             case Element.PCDATA:
  606.                 o.writeChars(getText());
  607.                 o.writeNewLine();
  608.                 break;
  609.             case Element.ENTITYREF:
  610.                 if (o.savingDTD) 
  611.                 {
  612.                     o.write('%');
  613.                 }
  614.                 else
  615.                 {
  616.                     o.write('&');
  617.                 }
  618.                 o.writeQualifiedName(getTagName(), getParent().getTagName().getNameSpace());
  619.                 o.writeChars(";");
  620.                 if (o.savingDTD)
  621.                     o.writeNewLine();
  622.                 break;
  623.             case Element.COMMENT:
  624.                 o.writeChars("<!--" + getText() + "-->");
  625.                 o.writeNewLine();
  626.                 break;
  627.             case Element.NAMESPACE:
  628.                 o.writeChars("<?xml:namespace ");
  629.                 saveAttributes(nameXML, o);
  630.                 o.writeChars("?>");
  631.                 o.writeNewLine();
  632.                 // record name space context
  633.                 Atom as, ns;
  634.                 
  635.                 as = Atom.create(getAttribute(nameXMLAS).toString());
  636.                 ns = Atom.create(getAttribute(nameXMLNS).toString());
  637.                 o.nameSpaceContext.addNameSpace(ns, as);
  638.                 break;
  639.             case Element.INCLUDESECTION:
  640.                 if (tag == null)
  641.                 {
  642.                     o.writeChars("<![INCLUDE[");
  643.                 }
  644.                 else
  645.                 {
  646.                     o.writeChars("<![%");
  647.                     o.writeChars(tag.toString());
  648.                     o.writeChars(";[");
  649.                 }
  650.                 for (ElementEnumeration ee = new ElementEnumeration(this); ee.hasMoreElements(); )
  651.                 {
  652.                     Element e = (Element)ee.nextElement();
  653.                     e.save(o);
  654.                 }
  655.                 o.writeChars("]]>");
  656.                 break;
  657.             case Element.IGNORESECTION:
  658.                 if (tag == null)
  659.                 {
  660.                     o.writeChars("<![IGNORE[");
  661.                 }
  662.                 else
  663.                 {
  664.                     o.writeChars("<![%");
  665.                     o.writeChars(tag.toString());
  666.                     o.writeChars(";[");
  667.                 }
  668.                 for (ElementEnumeration ee = new ElementEnumeration(this); ee.hasMoreElements(); )
  669.                 {
  670.                     Element e = (Element)ee.nextElement();
  671.                     e.save(o);
  672.                 }
  673.                 break;
  674.         }
  675.         o.flush();
  676.     }
  677.  
  678.     /**
  679.      * This is a useful method for creating a qualified Name object
  680.      * from the given string.  This will parse the string and lookup
  681.      * the namespace, if specified, and create the fully qualified
  682.      * name.  If no namespace is given, it will inherit the namespace
  683.      * from this element.
  684.      */
  685.     public Name qualifyName(String string)
  686.     {
  687.         int pos = string.indexOf(":");
  688.         if (pos != -1) {
  689.             int len = 1;
  690.             // support for old "::" namespace syntax.
  691.             if (pos+1 < string.length() && string.charAt(pos+1) == ':')
  692.                 len++;
  693.             String sn = string.substring(0,pos);
  694.             Atom namespace = getNamespace(sn);
  695.             String name = string.substring(pos+len);
  696.             return Name.create(name, namespace);
  697.         } else if (tag != null) {
  698.             return Name.create(string, tag.getNameSpace());
  699.         }
  700.         return Name.create(string);
  701.     }
  702.  
  703.     Atom getNamespace(String str)
  704.     {   
  705.         Atom name = Atom.create(str);
  706.         Document d = getDocument();
  707.         if (d != null) 
  708.         {
  709.             DTD dtd = d.getDTD();
  710.             if (dtd != null)
  711.             {
  712.                 Atom namespace = dtd.findLongNameSpace(name);
  713.                 if (namespace != null)
  714.                     return namespace;
  715.             }
  716.         }
  717.         return name;
  718.     }
  719.  
  720.     Document getDocument()
  721.     {
  722.         if (doc == null) 
  723.         {
  724.             Element e = this;
  725.             while (e.getParent() != null) 
  726.             {
  727.                 e = e.getParent();
  728.             }
  729.             if (e instanceof Document) 
  730.             {
  731.                 doc = (Document)e;
  732.             }
  733.         }
  734.         return doc;
  735.     }
  736.  
  737.     /**
  738.      * Tag of the element (markup).
  739.      */
  740.     Name tag;
  741.  
  742.     /**
  743.      * type of element.
  744.      */    
  745.     int type;
  746.     
  747.     /**
  748.      * Text for element.
  749.      */    
  750.     String text;
  751.     
  752.     /**
  753.      * Parent of element.
  754.      */    
  755.     Element parent;    
  756.     
  757.     /**
  758.      * Children element list.
  759.      */    
  760.     Vector children; 
  761.  
  762.     /**
  763.      * Cached pointer to owning Document
  764.      */
  765.     Document doc;
  766.     
  767.     /**
  768.      * The attribute list.
  769.      * 
  770.      */
  771.     protected Attributes attrlist;
  772.  
  773.     static Atom nameXML = Atom.create("xml");
  774.     static Name nameXMLSPACE = Name.create("xml-space","xml");
  775.     static Name nameXMLAS = Name.create("prefix", "xml");
  776.     static Name nameXMLHREF = Name.create("src", "xml");
  777.     static Name nameXMLNS = Name.create("ns", "xml");
  778. }
  779.