[ 
http://issues.apache.org/jira/browse/XERCESJ-1170?page=comments#action_12417643 
] 

hua lei commented on XERCESJ-1170:
----------------------------------

I'm not very familiar with the operating of JIRA, sorry for resend two empty 
letters. 

My source code is shown below. The attached source code of initial contribution 
works well under 
DOM 3 implementation, j2se 5.0. However, the stax feature aims to work under 
DOM 2 ,j2se 1.2. 
In the design, I encountered two problems:

 1) The method "public Location getLocation()".
This interface supplies the location of the StAX parser cursor. However, the 
DOM implementation reads the whole XML into the memory and doesn't supply this 
functionality. I think one possible solution is to keep the track of the 
DOMXMLStreamReader cursor, however, it will not always return the exact 
position. For example, the underlying DOM implementation may ignore some 
characters such as whitespace, the DOMXMLStreamReader will never know how many 
such characters are ignored. 
 
     2)  How to get the XML declaration information
The DOM level 3 supplies the interfaces to get XML declaration information such 
as getXmlVersion, getXmlStandalone(), etc. However, the DOM level 2 didn't 
supply these interfaces. One possible solution is to parse the XML declaration 
by myself, but not underlying DOM implementation. Because the XML declaration 
is always on the first line of XML document, so the parsing work is not very 
difficult. 


/*
 * Copyright 2006 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.xerces.stax;

import java.util.ArrayList;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLInputFactory;

import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.EntityReference;
import org.w3c.dom.CharacterData;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;

/**
 * 
 * @author Hua Lei
 *
 */
public class DOMXMLStreamReader implements XMLStreamReader
{  
      // The XMLInputFactory instance which creates the DOMXMLStreamReader
          private XMLInputFactory xif; 
        
          // The root node
          private Node domNode;
          
          // The following are four XML declration features
          private String xmlVersion;
          
          private boolean xmlStandalone;
          
          private String xmlEncoding;
          
          private String inputEncoding;
          
          // Record the cursor's position
          private Node curNode;
          
          // Record the current event type
          private int curType;
          
          // Represent whether the current node is the end element or not 
          private boolean elementEndFlag = false;
          
          // Represent "javax.xml.stream.isCoalescing" feature
          protected boolean isCoalesce = false;
          
          // Record the continue character nodes
          private int contiNum = 0;
          
          // Record the current attribute and namespace for StartElement event
          private ArrayList curAttrs;
          private ArrayList curNamespaces;
          
          // Record the current namespace context
          private DOMNamespaceContext dc;
          
          /**
           * The construction method of DOMXMLStreamReader
           * 
           * @param domNode
           * @param xif
           */
          public DOMXMLStreamReader(Node domNode, XMLInputFactory xif){
                  this.domNode = domNode;
                  this.xif = xif;
                  this.curNode = domNode;
                  curType = DOMUtility.getStAXType(domNode);
                  
                  curAttrs = new ArrayList();
                  curNamespaces = new ArrayList();
                  
                  isCoalesce = Boolean.getBoolean(xif.IS_COALESCING);
                  
                  dc = DOMNamespaceContext.getDOMNamespaceContext();
                  
                  if(curType == XMLStreamConstants.START_DOCUMENT){
                          Document doc = (Document)domNode;
                         
                          // DOM Level 3          
                          xmlVersion = doc.getXmlVersion();
                          xmlStandalone = doc.getXmlStandalone();
                          xmlEncoding = doc.getXmlEncoding();
                          inputEncoding = doc.getInputEncoding();
                  }
          }
          
          /**
           * Get the value of a feature/property from the underlying 
implementation
           *
           * @param name The name of the property, may not be null
           * @return The value of the property
           * @throws IllegalArgumentException if name is null
           */
          public Object getProperty(java.lang.String name) throws 
java.lang.IllegalArgumentException{
                  if(name == null)
                          throw new IllegalArgumentException("The feature name 
should not be null");
                  return xif.getProperty(name);
          }

          /**
           * Returns true if there are more parsing events and false
           * if there are no more events.  This method will return
           * false if the current state of the XMLStreamReader is
           * END_DOCUMENT
           * 
           * @return true if there are more events, false otherwise
           * @throws XMLStreamException if there is a fatal error detecting the 
next state
           */
          public boolean hasNext() throws XMLStreamException{
                  if(curType == XMLStreamConstants.END_DOCUMENT) return false;
                  return true;
          }
          
          /**
           * This method will throw an IllegalStateException if it is called 
after hasNext() returns false.
           *
           * @see javax.xml.stream.events.XMLEvent
           * @return the integer code corresponding to the current parse event
           * @throws NoSuchElementException if this is called when hasNext() 
returns false
           * @throws XMLStreamException  if there is an error processing the 
underlying XML source
           */
          public int next() throws XMLStreamException{
                  if(hasNext() == false){
                          throw new XMLStreamException("No such element!");
                  }
                  try{            
                          Node curChild = curNode.getFirstChild();
                          
                          // The current node has a child
                          if(curChild != null && !elementEndFlag){
                                  curNode = curChild;
                          }
                          // Go to the next sibling, if null, go to parent's 
next sibling
                          else{
                                  if(curNode instanceof Element && 
!elementEndFlag){
                                          elementEndFlag = true;
                                          curType = 
XMLStreamConstants.END_ELEMENT;
                                          initialElementAttrs();
                                          return curType;
                                  }
                                  
                                  if(curNode instanceof Document){
                                          curType = 
XMLStreamConstants.END_DOCUMENT;
                                          return curType;
                                  }
                                  
                                  Node curSibling = curNode.getNextSibling();
                                  elementEndFlag = false;
                                                  
                                  if(curSibling == null && 
curNode.getParentNode() != null){
                                          curNode = curNode.getParentNode();
                                          elementEndFlag = true;
                                          
                                          if(curNode instanceof Document){
                                                  curType = 
XMLStreamConstants.END_DOCUMENT;
                                                  return curType;
                                          }
                                          if(curNode instanceof Element){
                                                  elementEndFlag = true;
                                                  curType = 
XMLStreamConstants.END_ELEMENT;
                                                  initialElementAttrs();
                                                  return curType;
                                          }
                                  }
                                  curNode = curSibling;
                          }
                          curType = DOMUtility.getStAXType(curNode);
                          
                          initialElementAttrs();
                          
                          if(isCoalesce && curType == 
XMLStreamConstants.CHARACTERS){
                                  contiNum = 0;
                                  while(peekNext() == 
XMLStreamConstants.CHARACTERS){
                                          next();
                                          contiNum++;
                                  }
                          }
                          
                          return curType;
                  }catch(Exception e){
                          throw new XMLStreamException("Error occurs when 
processing DOMSource", e);
                  }
          }

          /**
           * Peek the next event
           * 
           * @return
           */
          private int peekNext(){
                if(curType == XMLStreamConstants.END_DOCUMENT){
                         return -1;
                 }
                
                Node peekNode = curNode;
                Node curChild = peekNode.getFirstChild();
                
                // The current node has a child
                if (curChild != null && !elementEndFlag) {
                        peekNode = curChild;
                }
                // Go to the next sibling, if null, go to parent's next sibling
                else {
                        if (peekNode instanceof Element && !elementEndFlag) {
                                return XMLStreamConstants.END_ELEMENT;
                        }

                        if (peekNode instanceof Document) {
                                return XMLStreamConstants.END_DOCUMENT;
                        }

                        Node curSibling = peekNode.getNextSibling();

                        if (curSibling == null && peekNode.getParentNode() != 
null) {
                                peekNode = peekNode.getParentNode();

                                if (peekNode instanceof Document) {
                                        return XMLStreamConstants.END_DOCUMENT;
                                }
                                if (peekNode instanceof Element) {
                                        return XMLStreamConstants.END_ELEMENT;
                                }
                        }
                        peekNode = curSibling;
                }
                
                return DOMUtility.getStAXType(peekNode);
          }
          
          /**
                 * This method is to record attribute(not namespace) and 
namespace of
                 * current element
                 * 
                 */
          private void initialElementAttrs(){
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT ){
                          curAttrs.clear();
                          curNamespaces.clear();
                          NamedNodeMap attrs = curNode.getAttributes();
                          if(attrs != null){
                                  for(int i = 0; i < attrs.getLength(); i++){
                                          Attr attr = (Attr)attrs.item(i);
                                          String name = attr.getName();
                                          if(name.startsWith("xmlns")){
                                                  String value = 
attr.getValue();
                                                  String prefix = "";
                                                  if(!name.equals("xmlns"))
                                                          prefix += 
name.substring(6);
                                                        
                                                  if(curType == 
XMLStreamConstants.START_ELEMENT)
                                                          
dc.addNamespace(prefix, value);  
                                                  curNamespaces.add(attr);
                                          }
                                          else
                                                  curAttrs.add(attr);
                                  }
                          }
                          if(curType == XMLStreamConstants.START_ELEMENT)
                                  dc.onStartElement();
                          if(curType == XMLStreamConstants.END_ELEMENT)
                                  dc.onEndElement();
                  }
          }
          
          /**
           * Test if the current event is of the given type and if the 
namespace and name match the current
           * namespace and name of the current event.  If the namespaceURI is 
null it is not checked for equality,
           * if the localName is null it is not checked for equality.
           * @param type the event type
           * @param namespaceURI the uri of the event, may be null
           * @param localName the localName of the event, may be null
           * @throws XMLStreamException if the required values are not matched.
           */
          public void require(int type, String namespaceURI, String localName) 
throws XMLStreamException{
                   String curNamespaceURI = curNode.getNamespaceURI();
                   String curLocalName = curNode.getLocalName();
                   if(type != curType)
                           throw new XMLStreamException("The event type doesn't 
match with current node");
                   if(namespaceURI != null && 
!namespaceURI.equals(curNamespaceURI))
                           throw new XMLStreamException("The namespaceURI "+ 
namespaceURI + " doesn't match with current node "+ curNamespaceURI);
                   if(localName != null && !localName.equals(curLocalName))
                           throw new XMLStreamException("The localName "+ 
localName + " doesn't match with current node "+ curLocalName);
          }
          

          /**
           * Reads the content of a text-only element, an exception is thrown 
if this is
           * not a text-only element.
           * Regardless of value of javax.xml.stream.isCoalescing this method 
always returns coalesced content.
           
           * <br /> Precondition: the current event is START_ELEMENT.
           * <br /> Postcondition: the current event is the corresponding 
END_ELEMENT.
           *
           * @throws XMLStreamException if the current event is not a 
START_ELEMENT 
           * or if a non text element is encountered
           */
          public String getElementText() throws XMLStreamException{
                if (getEventType() != XMLStreamConstants.START_ELEMENT) {
                        throw new XMLStreamException(
                                        "parser must be on START_ELEMENT to 
read next text",
                                        getLocation());
                }
                int eventType = next();
                StringBuffer buf = new StringBuffer();
                while (eventType != XMLStreamConstants.END_ELEMENT) {
                        if (eventType == XMLStreamConstants.CHARACTERS
                                        || eventType == XMLStreamConstants.CDATA
                                        || eventType == XMLStreamConstants.SPACE
                                        || eventType == 
XMLStreamConstants.ENTITY_REFERENCE) {
                                buf.append(getText());
                        } 
                        else if (eventType == 
XMLStreamConstants.PROCESSING_INSTRUCTION
                                        || eventType == 
XMLStreamConstants.COMMENT) {
                                // skipping
                        } 
                        else if (eventType == XMLStreamConstants.END_DOCUMENT) {
                                throw new XMLStreamException(
                                                "unexpected end of document 
when reading element text content", getLocation());
                        } 
                        else if (eventType == XMLStreamConstants.START_ELEMENT) 
{
                                throw new XMLStreamException(
                                                "element text content may not 
contain START_ELEMENT",
                                                getLocation());
                        } 
                        else {
                                throw new XMLStreamException("Unexpected event 
type "
                                                + eventType, getLocation());
                        }
                        eventType = next();
                }
                return buf.toString();
          }

          /**
           * Skips any white space (isWhiteSpace() returns true), COMMENT,
           * or PROCESSING_INSTRUCTION,
           * until a START_ELEMENT or END_ELEMENT is reached.
           * If other than white space characters, COMMENT, 
PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT
           * are encountered, an exception is thrown. 
           * return eventType;
           * </pre>
           *
           * @return the event type of the element read (START_ELEMENT or 
END_ELEMENT)
           * @throws XMLStreamException if the current event is not white 
space, PROCESSING_INSTRUCTION,
           * START_ELEMENT or END_ELEMENT
           * @throws NoSuchElementException if this is called when hasNext() 
returns false
           */
          public int nextTag() throws XMLStreamException{
                int eventType = next();
                while ((eventType == XMLStreamConstants.CHARACTERS && 
isWhiteSpace()) // skip                                                         
                                                                                
  // //                                                                         
                                                                          // 
whitespace
                                || (eventType == XMLStreamConstants.CDATA && 
isWhiteSpace())
                                // skip whitespace
                                || eventType == XMLStreamConstants.SPACE
                                || eventType == 
XMLStreamConstants.PROCESSING_INSTRUCTION
                                || eventType == XMLStreamConstants.COMMENT) {
                        eventType = next();
                }
                if (eventType != XMLStreamConstants.START_ELEMENT
                                && eventType != XMLStreamConstants.END_ELEMENT) 
{
                        throw new XMLStreamException("expected start or end 
tag",
                                        getLocation());
                }
                return eventType;

          }
          
          /**
           * Frees any resources associated with this Reader.  This method does 
not close the
           * underlying input source.
           * @throws XMLStreamException if there are errors freeing associated 
resources
           */
          public void close() throws XMLStreamException{
                  // As for DOMSource, this method seems has nothing to do
          }

          /**
           * Return the uri for the given prefix.
           * The uri returned depends on the current state of the processor.
           *
           * For DOMSource, the method will track back util the root node
           *
           * @param prefix The prefix to lookup, may not be null
           * @return the uri bound to the given prefix or null if it is not 
bound
           * @throws IllegalArgumentException if the prefix is null
           */
          public String getNamespaceURI(String prefix){
                  if(prefix == null) 
                          throw new IllegalStateException("The prefix should 
not be null");
                  
                  if(prefix == "xml") return 
"http://www.w3.org/XML/1998/namespace";;
                  if(prefix == "xmlns") return "http://www.w3.org/2000/xmlns";;
                   
                  Node workNode = curNode;
                  int workType = curType;
                  
                  String namespaceDef = "xmlns";
                  if(!prefix.equals(""))
                    namespaceDef += ":"+ prefix;
                  
                  while(workNode != domNode){
                     if(workType == XMLStreamConstants.START_ELEMENT || 
workType == XMLStreamConstants.START_ELEMENT){
                         NamedNodeMap nodes = workNode.getAttributes();
                         Attr attr = (Attr)nodes.getNamedItem(namespaceDef);
                         if(attr != null){
                                 return attr.getValue();
                         }
                     }
                     workNode = workNode.getParentNode();
                     workType = DOMUtility.getStAXType(workNode);
                  }
                  return null;
          }

          /**
           * Returns true if the cursor points to a start tag (otherwise false)
           * @return true if the cursor points to a start tag, false otherwise
           */
          public boolean isStartElement(){
                  
                  return curType == XMLStreamConstants.START_ELEMENT;
          }

          /**
           * Returns true if the cursor points to an end tag (otherwise false)
           * @return true if the cursor points to an end tag, false otherwise
           */
          public boolean isEndElement(){
                  return curType == XMLStreamConstants.END_ELEMENT;
          }

          /**
           * Returns true if the cursor points to a character data event
           * @return true if the cursor points to character data, false 
otherwise
           */
          public boolean isCharacters(){
                  return curType == XMLStreamConstants.CHARACTERS;
          }

          /**
           * Returns true if the cursor points to a character data event
           * that consists of all whitespace
           * @return true if the cursor points to all whitespace, false 
otherwise
           */
          public boolean isWhiteSpace(){
                  if(curType == XMLStreamConstants.CHARACTERS){
                          CharacterData cd = (CharacterData)curNode;
                          String data = cd.getData();
                          if(data != null){
                                  for(int i = 0; i < data.length(); i++){
                                          char c = data.charAt(i);
                                          // The white space is tab, enter, and 
blank
                                          // by 
http://www.w3.org/TR/2004/REC-xml-20040204/#sec-white-space
                                          if(c == '\t' || c == '\n' || c == ' 
') continue;
                                          return false;
                                  }
                                  return true;
                          }
                  }
                  return false;
          }


          /**
           * Returns the normalized attribute value of the
           * attribute with the namespace and localName
           * If the namespaceURI is null the namespace
           * is not checked for equality
           * @param namespaceURI the namespace of the attribute
           * @param localName the local name of the attribute, cannot be null
           * @return returns the value of the attribute , returns null if not 
found
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public String getAttributeValue(String namespaceURI,
                                          String localName){
                  if(curType == XMLStreamConstants.START_ELEMENT){
                          NamedNodeMap attributes = curNode.getAttributes();
                         
                          Attr attr = (Attr)attributes.getNamedItem(localName);
                          if(attr!= null ){
                                 if(namespaceURI != null && 
!namespaceURI.equals(attr.getNamespaceURI())){
                                          return null;
                                 }
                                 
                                 return attr.getValue();
                          }       
                  }
                  if(curType == XMLStreamConstants.ATTRIBUTE){
                          Attr attr = (Attr)curNode;
                         
                          if(namespaceURI != null && 
!namespaceURI.equals(attr.getNamespaceURI())){
                                  return null;
                          }
                          return attr.getValue();
                  }
                  throw new IllegalStateException("Current event is not 
START_ELEMENT or ATTRIBUTE");
          }

          /**
           * Returns the count of attributes on this START_ELEMENT,
           * this method is only valid on a START_ELEMENT or ATTRIBUTE.  This
           * count excludes namespace definitions.  Attribute indices are
           * zero-based.
           * @return returns the number of attributes
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public int getAttributeCount(){
                 int count = 0;
                 String attrName;
         if (curType == XMLStreamConstants.START_ELEMENT) {
                        
            return curAttrs.size();
                }
                if (curType == XMLStreamConstants.ATTRIBUTE) {
                        Attr attr = (Attr) curNode;

                        attrName = attr.getName();
                        if(!attrName.startsWith("xmlns")) return 1;
                        return 0;
                }
                throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");
          }

          /**
                 * Returns the qname of the attribute at the provided index
                 * This method excludes namespace definitions
                 * 
                 * @param index
                 *            the position of the attribute
                 * @return the QName of the attribute
                 * @throws IllegalStateException
                 *             if this is not a START_ELEMENT or ATTRIBUTE
                 */
          public QName getAttributeName(int index){
                  String localName;
                  String namespaceURI;
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);
                        localName = attr.getName();
                        namespaceURI = attr.getNamespaceURI();
                
                return new QName(namespaceURI, localName);
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;

                        localName = attr.getName();
                namespaceURI = attr.getNamespaceURI();
                return new QName(namespaceURI, localName);
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");                     
          }
          
          /**
           * Returns the namespace of the attribute at the provided
           * index
           * @param index the position of the attribute
           * @return the namespace URI (can be null)
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public String getAttributeNamespace(int index){
                  String namespaceURI;
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);
                        namespaceURI = attr.getNamespaceURI();
                
                return namespaceURI;
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;

                namespaceURI = attr.getNamespaceURI();
                return namespaceURI;
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");             
          }

          /**
           * Returns the localName of the attribute at the provided
           * index
           * @param index the position of the attribute
           * @return the localName of the attribute
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public String getAttributeLocalName(int index){
                  String localName;
                  
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);
                        localName = attr.getLocalName();
                
                return localName;
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;

                        localName = attr.getLocalName();
                return localName;
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");     
          }

          /**
           * Returns the prefix of this attribute at the
           * provided index
           * @param index the position of the attribute
           * @return the prefix of the attribute
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public String getAttributePrefix(int index){
          String prefix;
                  
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);
                        prefix = attr.getPrefix();
                
                return prefix;
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;
            prefix = attr.getPrefix();
                return prefix;
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");     
          }

          /**
           * Returns the XML type of the attribute at the provided
           * index
           * @param index the position of the attribute
           * @return the XML type of the attribute
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public String getAttributeType(int index){
          String type;
                  
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);
            // DOM Level 3
                        type = attr.getSchemaTypeInfo().getTypeName();
                
                return type;
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;
                        type = attr.getSchemaTypeInfo().getTypeName();
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");     
          }

          /**
           * Returns the value of the attribute at the
           * index
           * @param index the position of the attribute
           * @return the attribute value
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public String getAttributeValue(int index){
          String value;
                  
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);
                        value = attr.getValue();
                
                return value;
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;
                        value = attr.getValue();
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");     
          }
          

          /**
           * Returns a boolean which indicates if this
           * attribute was created by default
           * @param index the position of the attribute
           * @return true if this is a default attribute
           * @throws IllegalStateException if this is not a START_ELEMENT or 
ATTRIBUTE
           */
          public boolean isAttributeSpecified(int index){
                  Attr attr = null;
                  
                  if (curType == XMLStreamConstants.START_ELEMENT) {
            int leng = getAttributeCount();
            if(index + 1 > leng || index < 0)
                throw new IndexOutOfBoundsException("The index "+ index+ " 
should be between 0..."+ (leng-1));
          
            attr = (Attr) curAttrs.get(index);                  
                return attr.getSpecified();
                  }
                  if (curType == XMLStreamConstants.ATTRIBUTE) {
                        attr = (Attr) curNode;
                        return attr.getSpecified();
                 }
                  throw new IllegalStateException(
                                "Current event is not START_ELEMENT or 
ATTRIBUTE");     
          }

          /**
           * Returns the count of namespaces declared on this START_ELEMENT or 
END_ELEMENT.
           * This method is only valid on a START_ELEMENT, END_ELEMENT or 
NAMESPACE.
           * On an END_ELEMENT the count is of the namespaces that are about to 
go
           * out of scope.  This is the equivalent of the information reported
           * by SAX callback for an end element event.
           * @return returns the number of namespace declarations on this 
specific element
           * @throws IllegalStateException if this is not a START_ELEMEN or, 
END_ELEMENT
           */
          public int getNamespaceCount(){
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT){
                          return curNamespaces.size();
                  }
                  if(curType == XMLStreamConstants.NAMESPACE)
                          return 1;
                  return 0;
          }

          /**
           * Returns the prefix for the namespace declared at the
           * index.  Returns null if this is the default namespace
           * declaration
           *
           * @param index the position of the namespace declaration
           * @return returns the namespace prefix
           * @throws IllegalStateException if this is not a START_ELEMENT,
           *    END_ELEMENT or NAMESPACE
           */
          public String getNamespacePrefix(int index){
                  Attr namespace; 
                  String attrName;
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT){
                          int leng = getNamespaceCount();
                  if(index + 1 > leng || index < 0)
                        throw new IndexOutOfBoundsException("The index "+ 
index+ " should be between 0..."+ (leng-1));
                          namespace = (Attr)curNamespaces.get(index);
                          attrName = namespace.getName();
                          if(attrName.equals("xmlns")) return null;
                          
                          return attrName.substring(6, attrName.length());
                  }
                  if(curType == XMLStreamConstants.NAMESPACE){
                          int leng = getNamespaceCount();
                  if(index + 1 > leng || index < 0)
                        throw new IndexOutOfBoundsException("The index "+ 
index+ " should be between 0..."+ (leng-1));
                          namespace = (Attr)curNode;
                          attrName = namespace.getName();
              if(attrName.equals("xmlns")) return null;
  
                          return attrName.substring(6, attrName.length());
                  }
                          
                  throw new IllegalStateException(
                        "Current event is not START_ELEMENT,END_ELEMENT or 
ATTRIBUTE"); 
          }
          
          /**
           * Returns the uri for the namespace declared at the
           * index.
           *
           * @param index the position of the namespace declaration
           * @return returns the namespace uri
           * @throws IllegalStateException if this is not a START_ELEMENT,
           *   END_ELEMENT or NAMESPACE
           */
          public String getNamespaceURI(int index){
                  Attr namespace; 
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT){
                          namespace = (Attr)curNamespaces.get(index);
                          return namespace.getValue();
                  }
                  if(curType == XMLStreamConstants.NAMESPACE){
                          namespace = (Attr)curNode;
                          return namespace.getValue();
                  }
                          
                  throw new IllegalStateException(
                        "Current event is not START_ELEMENT,END_ELEMENT or 
ATTRIBUTE"); 
          }

          /**
           * Returns a read only namespace context for the current
           * position.  The context is transient and only valid until
           * a call to next() changes the state of the reader.
           *
           * @return return a namespace context
           */
          public NamespaceContext getNamespaceContext(){
                  return dc;
          }

          /**
           * Returns an integer code that indicates the type
           * of the event the cursor is pointing to.
           */
          public int getEventType(){
                  return curType;
          }

          /**
           * Returns the current value of the parse event as a string,
           * this returns the string value of a CHARACTERS event,
           * returns the value of a COMMENT, the replacement value
           * for an ENTITY_REFERENCE, the string value of a CDATA section,
           * the string value for a SPACE event,
           * or the String value of the internal subset of the DTD.
           * If an ENTITY_REFERENCE has been resolved, any character data
           * will be reported as CHARACTERS events.
           * 
           * The DOM nodes Text, Comment, and CDATASection extends 
CharacterData, which
           * will map to StAX character events. 
           * 
           * @return the current text or null
           * @throws java.lang.IllegalStateException if this state is not
           * a valid text state.
           */
          public String getText(){
                  // XMLStreamConstants.SPACE and XMLStreamConstants.CDATA怀are 
                  // reported as XMLStreamConstants.CHARACTERS
                  if(curType == XMLStreamConstants.CHARACTERS){
                          String text = "";
                          CharacterData cur = (CharacterData)curNode;
                          if(this.isCoalesce){
                                  text = cur.getData();
                                  while(contiNum >0){
                                          cur = 
(CharacterData)cur.getPreviousSibling();
                                          text = cur.getData()+ text;
                                          contiNum--;
                                  }
                          }
                          else{
                                  text = cur.getData();
                          }
                          return text;
                  }
                  if(curType == XMLStreamConstants.COMMENT){
                          Comment cd = (Comment)curNode;
                          return cd.getData();
                  }
          if(curType == XMLStreamConstants.DTD){
                  DocumentType dt = (DocumentType)curNode;
                  return dt.getInternalSubset();
                  }
          // Need to be tested...
          if(curType == XMLStreamConstants.ENTITY_REFERENCE){
                  EntityReference er = (EntityReference)curNode;
                  return er.getTextContent();
                  }
          throw new IllegalStateException(
                        "The current event is not a valid text state.");        
          }

          /**
           * Returns an array which contains the characters from this event.
           * This array should be treated as read-only and transient. I.e. the 
array will
           * contain the text characters until the XMLStreamReader moves on to 
the next event.
           * Attempts to hold onto the character array beyond that time or 
modify the
           * contents of the array are breaches of the contract for this 
interface.
           * 
           * @return the current text or an empty array
           * @throws java.lang.IllegalStateException if this state is not
           * a valid text state.
           */
          public char[] getTextCharacters(){
                  String text = getText();
                  return text.toCharArray();
          }

          /**
           * Gets the the text associated with a CHARACTERS, SPACE or CDATA 
event.  
           * Text starting a "sourceStart" is copied into "target" starting at 
"targetStart".  
           * Up to "length" characters are copied.  The number of characters 
actually copied is returned.
           *
           * XMLStreamException may be thrown if there are any XML errors in 
the underlying source. 
           * The "targetStart" argument must be greater than or equal to 0 and 
less than the length of "target",  
           * Length must be greater than 0 and "targetStart + length" must be 
less than or equal to length of "target".  
           *
           * @param sourceStart the index of the first character in the source 
array to copy
           * @param target the destination array
           * @param targetStart the start offset in the target array
           * @param length the number of characters to copy
           * @return the number of characters actually copied
           * @throws XMLStreamException if the underlying XML source is not 
well-formed
           * @throws IndexOutOfBoundsException if targetStart < 0 or > than the 
length of target
           * @throws IndexOutOfBoundsException if length < 0 or targetStart + 
length > length of target
           * @throws UnsupportedOperationException if this method is not 
supported 
           * @throws NullPointerException is if target is null
           */
           public int getTextCharacters(int sourceStart, char[] target, int 
targetStart, int length) 
             throws XMLStreamException{
              
                if(target == null)
                        throw new NullPointerException();

                int targetLen = target.length;
                
                if (targetStart < 0 || targetStart > targetLen)
                    throw new ArrayIndexOutOfBoundsException("The start 
position of target is out of index");
                
                
                if(length < 0)
                    throw new ArrayIndexOutOfBoundsException("The length is out 
of index");
                        
                int len = getTextLength();
                if (sourceStart < 0 || sourceStart > len) {
                    throw new ArrayIndexOutOfBoundsException("The start 
position of source is out of index");
                }

               
                int avail = len - sourceStart;

                if (avail < length) {
                    length = avail;
                }

               
                char[] intBuf = getTextCharacters();
                int intStart = getTextStart();
                System.arraycopy(intBuf, intStart + sourceStart,
                                     target, targetStart, length);
                return length;
           }

          /**
           * Returns the offset into the text character array where the first
           * character (of this text event) is stored.
           * @throws java.lang.IllegalStateException if this state is not
           * a valid text state.
           */
          public int getTextStart(){
                   return 0;
           }

          /**
           * Returns the length of the sequence of characters for this
           * Text event within the text character array.
           * @throws java.lang.IllegalStateException if this state is not
           * a valid text state.
           */
          public int getTextLength(){
                  String text = getText();
                  return text.length();
           }

          /**
           * Return input encoding if known or null if unknown.
           * @return the encoding of this instance or null
           */
          public String getEncoding(){
                   return inputEncoding;
           }

          /**
           * Return true if the current event has text, false otherwise
           * The following events have text:
           * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
           */
          public boolean hasText(){
                  if(curType == XMLStreamConstants.CHARACTERS || curType == 
XMLStreamConstants.ENTITY_REFERENCE ||
                                  curType == XMLStreamConstants.COMMENT || 
curType == XMLStreamConstants.SPACE || curType == XMLStreamConstants.DTD)
                          return true;
                  else
                          return false;
           }

          /**
           * Return the current location of the processor.
           * If the Location is unknown the processor should return
           * an implementation of Location that returns -1 for the
           * location and null for the publicId and systemId.
           * The location information is only valid until next() is
           * called.
           */
          public Location getLocation(){
                  return null;
          }

          /**
           * Returns a QName for the current START_ELEMENT or END_ELEMENT event
           *
           * 
           * @return the QName for the current START_ELEMENT or END_ELEMENT 
event
           * @throws IllegalStateException if this is not a START_ELEMENT or
           * END_ELEMENT
           */
          public QName getName(){
                  // DOM Level 2          
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT){ 
                          return new QName(curNode.getLocalName(), 
curNode.getNamespaceURI());
                  }
                  return null;
          }

          /**
           * Returns the (local) name of the current event.
           * For START_ELEMENT or END_ELEMENT returns the (local) name of the 
current element.
           * For ENTITY_REFERENCE it returns entity name.
           * The current event must be START_ELEMENT or END_ELEMENT, 
           * or ENTITY_REFERENCE
           * @return the localName
           * @throws IllegalStateException if this not a START_ELEMENT,
           * END_ELEMENT or ENTITY_REFERENCE
           */
          public String getLocalName(){
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT){
                          return curNode.getLocalName();
                  }
                  else if(curType == XMLStreamConstants.START_ELEMENT){
                          EntityReference er = (EntityReference)curNode;
                          
                          // Not quite sure
                          return er.getNodeName();
                  }
                  else
                          return null;
          }

          /**
           * returns true if the current event has a name (is a START_ELEMENT 
or END_ELEMENT)
           * returns false otherwise
           */
          public boolean hasName(){
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.END_ELEMENT)
                     return true;
                  else 
                         return false;
          }

          /**
           * If the current event is a START_ELEMENT or END_ELEMENT  this method
           * returns the URI of the current element (URI mapping to the prefix
           * element/attribute has, if any; or if no prefix, null for attribute,
           * and the default namespace URI for the element).
           *
           * @return the URI bound to this elements prefix, the default 
namespace, or null
           * @throws IllegalStateException if this is not a START_ELEMENT, 
END_ELEMENT
           *    or ATTRIBUTE
           */
          public String getNamespaceURI(){
                  String namespaceURI = curNode.getNamespaceURI();
                  if(curType == XMLStreamConstants.START_ELEMENT
                                || curType == XMLStreamConstants.START_ELEMENT){
                       if(namespaceURI != null)
                          return namespaceURI;
                       else{
                                  // DOM Level 3
                           return curNode.getBaseURI();
                       }
                  }
                  else if(curType == XMLStreamConstants.ATTRIBUTE){
                          return namespaceURI;
                  }
                  else
                          return null;
          }

          /**
           * Returns the prefix of the current event or null if the event does 
not
           * have a prefix
           * @return the prefix or null
           * @throws IllegalStateException if this is not a START_ELEMENT or 
END_ELEMENT
           */
          public String getPrefix(){
                  if(curType == XMLStreamConstants.START_ELEMENT || curType == 
XMLStreamConstants.START_ELEMENT)
                          return curNode.getPrefix();
                  return null;
          }
          
          /**
           * Get the xml version declared on the xml declaration
           * Returns null if none was declared
           * @return the XML version or null
           */
          public String getVersion(){
                  return xmlVersion;
          }

          /**
           * Get the standalone declaration from the xml declaration, if one 
found
           * ([EMAIL PROTECTED] #standaloneSet} returns true if one was 
specified).
           *
           * @return true if this is standalone, or false otherwise
           */
          public boolean isStandalone(){
                  return xmlStandalone;
          }

          /**
           * Checks if standalone was set in the document
           * Since we only have DOMSource, the standaloneSet information is 
hard to 
           * get. Because the default standalone is false, if the standalone is 
true
           * then it was set.
           * 
           * @return true if standalone was set in the document, or false 
otherwise
           */
          public boolean standaloneSet(){
                  if(xmlStandalone == false) return false;
                  return true;
          }

          /**
           * Returns the character encoding declared on the xml declaration
           * Returns null if none was declared
           * @return the encoding declared in the document or null
           */
          public String getCharacterEncodingScheme(){
                  return xmlEncoding;
          }

          /**
           * Get the target of a processing instruction
           * @return the target
           * @throws IllegalStateException if the current event is not a
           *   [EMAIL PROTECTED] XMLStreamConstants#PROCESSING_INSTRUCTION}
           */
          public String getPITarget() {
                  if(curType == XMLStreamConstants.PROCESSING_INSTRUCTION){
                          ProcessingInstruction pi = 
(ProcessingInstruction)curNode;
                          return pi.getTarget();
                  }
                  else{
                          return null;
                  }
          }

          /**
           * Get the data section of a processing instruction
           * @return the data (if processing instruction has any), or null
           *    if the processing instruction only has target.
           * @throws IllegalStateException if the current event is not a
           *   [EMAIL PROTECTED] XMLStreamConstants#PROCESSING_INSTRUCTION}
           */
          public String getPIData(){
                  if(curType == XMLStreamConstants.PROCESSING_INSTRUCTION){
                          ProcessingInstruction pi = 
(ProcessingInstruction)curNode;
                          return pi.getData();
                  }
                  else{
                          return null;
                  }
          }
}


package org.apache.xerces.stax;

import java.util.Iterator;
import java.util.Stack;
import java.util.ArrayList;

import javax.xml.namespace.NamespaceContext;
import javax.xml.XMLConstants;

/**
 * 
 * @author Hua Lei
 *
 */
public class DOMNamespaceContext implements NamespaceContext{
        
        private static DOMNamespaceContext context;
        
        // Record the avaliable namespaces
        private Stack namespaceStack;
        
        /**
         * The initialization method of DOMNamespaceContext, 
         * the DOMNamespaceContext is a singleton
         *
         */
        private DOMNamespaceContext(){
                namespaceStack = new Stack();
        }
        
        /**
         * Factory method to create a DOMNamespaceContext instance
         * 
         * @return
         */
        public static DOMNamespaceContext getDOMNamespaceContext(){
                if(context == null) return new DOMNamespaceContext();
                return context;
        }
        
        /**
         * When encounters a StartElement event, the namespace level in the 
namespace
         * stack is increased.
         *
         */
        public void onStartElement(){
                if(!namespaceStack.empty()){
                        Iterator iter = namespaceStack.iterator();
                        while(iter.hasNext()){
                                DOMNamespace dc = (DOMNamespace)iter.next();
                                dc.increaseLevel();
                        }
                }
        }
        
        /**
         * When encounters a StartElement event, the namespace level in the 
namespace
         * stack is decreased. If the level is less than 0, the namespace is 
out of scope
         * and removed from avaliable stack.
         */
        public void onEndElement(){
                if(!namespaceStack.empty()){
                        
                        Iterator iter = namespaceStack.iterator();
                        
                        while(iter.hasNext()){
                                DOMNamespace dc = (DOMNamespace)iter.next();
                                int level = dc.decreaseLevel();
                                
                                if(level <= 0){
                                        int index = namespaceStack.indexOf(dc);
                                        int deleteNum = namespaceStack.size() - 
index;
                                        while(deleteNum-- > 0)
                                        namespaceStack.pop();
                                        return;
                                }
                        }
                }
        }
        
        /**
         * Add the prefix and namespaceURI to the namespace stack
         * 
         * @param prefix
         * @param namespaceURI
         */
        public void addNamespace(String prefix, String namespaceURI){
                DOMNamespace dn = new DOMNamespace(prefix, namespaceURI);
                namespaceStack.push(dn);
        }
        
        /**
         * Implement the interface of NamespaceContext
         */
        public String getNamespaceURI(String prefix){
                if(prefix == null)
                        throw new IllegalArgumentException("The input prefix 
should not be null");
                
                if(prefix.equals("xml")) return XMLConstants.XML_NS_URI;
                if(prefix.equals("xmlns")) return 
XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
                
                int size = namespaceStack.size();

                while (size > 0) {
                        DOMNamespace dc = (DOMNamespace) 
namespaceStack.elementAt(--size);
                        String pre = dc.getPrefix();
                        if (prefix.equals(pre))
                                return dc.getNamespaceURI();
                }
                
                return null;
        }
        
        /**
         * Implement the interface of NamespaceContext
         */
        public String getPrefix(String namespaceURI){
                if(namespaceURI == null)
                        throw new IllegalArgumentException("The input 
namespaceURI should not be null");
                
                if(namespaceURI.equals(XMLConstants.XML_NS_URI)) return "xml";
                if(namespaceURI.equals(XMLConstants.XML_NS_URI)) return "xmlns";
                
                int size = namespaceStack.size();

                while (size > 0) {
                        DOMNamespace dc = (DOMNamespace) 
namespaceStack.elementAt(--size);
                        String namespace = dc.getNamespaceURI();
                        if (namespaceURI.equals(namespace))
                                return dc.getPrefix();
                }
                
                return null;
        }
        
        /**
         * Implement the interface of NamespaceContext
         */
        public Iterator getPrefixes(String namespaceURI){
                if(namespaceURI == null)
                        throw new IllegalArgumentException("The input 
namespaceURI should not be null");
                ArrayList prefixes = new ArrayList();
                
                if(!namespaceStack.empty()){
                        Iterator iter = namespaceStack.iterator();
                        while(iter.hasNext()){
                                DOMNamespace dc = (DOMNamespace)iter.next();
                                String namespace = dc.getNamespaceURI();
                                if(namespaceURI.equals(namespace))
                                        prefixes.add(dc.getPrefix());
                        }
                }
                
                return prefixes.iterator();
        }
        
        /**
         * Class to represent the namespace in DOMSource
         * 
         * @author Hua Lei
         *
         */
        class DOMNamespace{
                private String prefix;
                private String namespaceURI;
                private int level;
                
                DOMNamespace(String prefix, String namespaceURI){
                        this.prefix = prefix;
                        this.namespaceURI = namespaceURI;
                        level = 0;
                }
                
                int decreaseLevel(){
                        level--;
                        return level;
                }
                
                void increaseLevel(){
                        level++;
                }
                
                String getPrefix(){
                        return prefix;
                }
                
                String getNamespaceURI(){
                        return namespaceURI;
                }
                
                int getLevel(){
                        return level;
                }
        }
        
        
}


import javax.xml.stream.XMLStreamConstants;

// DOM Core Module
import org.w3c.dom.Node;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Element;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Text; 

// DOM XML Module
import org.w3c.dom.CDATASection;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Notation;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.DocumentType;


public class DOMUtility {
    public static int getStAXType(Node node){
                if(node instanceof Attr){
                        return XMLStreamConstants.ATTRIBUTE;
                }
                if(node instanceof Comment){
                        return XMLStreamConstants.COMMENT;
                }
                if(node instanceof Element){
                        return XMLStreamConstants.START_ELEMENT;
                }
                if(node instanceof Document){
                        return XMLStreamConstants.START_DOCUMENT;
                }
                if(node instanceof CDATASection){
                        return XMLStreamConstants.CHARACTERS;
                }
                if(node instanceof Text){
          // Include XMLStreamConstants.space
                        return XMLStreamConstants.CHARACTERS;
                }
                if(node instanceof DocumentType){
                        return XMLStreamConstants.DTD;
                }
                if(node instanceof EntityReference){
                        return XMLStreamConstants.ENTITY_REFERENCE;
                }
                if(node instanceof Entity){
                        return XMLStreamConstants.ENTITY_DECLARATION ;
                }
                if(node instanceof Notation){
                        return XMLStreamConstants.NOTATION_DECLARATION ;
                }
                if(node instanceof ProcessingInstruction){
                        return XMLStreamConstants.PROCESSING_INSTRUCTION; 
                }
                return -1;
    }
}



> Initial contribution for the DOM XMLStreamReader
> ------------------------------------------------
>
>          Key: XERCESJ-1170
>          URL: http://issues.apache.org/jira/browse/XERCESJ-1170
>      Project: Xerces2-J
>         Type: New Feature

>   Components: StAX
>     Versions: 2.8.0
>  Environment: Windows XP Pro, sp2; Eclipse 3.1
>     Reporter: hua lei

>
>         StAX feature is one project of google's summer of code. "By  the 
> Using an  XMLInputFactory an  XMLStreamReader can be constructed from a  
> SAXSource or  DOMSource. The goal here is to provide support for both of 
> these sources, making it possible for applications to process the results of 
> a SAX pipeline in a pull fashion and to incrementally walk a DOM tree through 
> the  XMLStreamReader interface."  
>         This issue is the initial contribution for DOMStreamReader. 

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to