[ 
https://issues.apache.org/jira/browse/XERCESJ-1113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13056966#comment-13056966
 ] 

Ishara Karunarathna commented on XERCESJ-1113:
----------------------------------------------

Hi Michael and Devs, 

Here I have posted the latest implemented code for xml:id parser component. And 
I want to know suggestions and comments on my approach.


package org.apache.xerces.xmlID;

import org.apache.xerces.impl.Constants;
import org.apache.xerces.impl.XMLErrorReporter;
import org.apache.xerces.impl.dtd.XMLAttributeDecl;
import org.apache.xerces.impl.dtd.XMLSimpleType;
import org.apache.xerces.impl.dv.DTDDVFactory;
import org.apache.xerces.impl.dv.DatatypeValidator;
import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
import org.apache.xerces.impl.dv.dtd.IDDatatypeValidator;
import org.apache.xerces.impl.msg.XMLMessageFormatter;
import org.apache.xerces.impl.validation.ValidationManager;
import org.apache.xerces.impl.validation.ValidationState;
import org.apache.xerces.util.SymbolTable;
import org.apache.xerces.util.XMLSymbols;
import org.apache.xerces.xni.QName;
import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.Augmentations;
import org.apache.xerces.xni.NamespaceContext;
import org.apache.xerces.xni.XMLDocumentHandler;
import org.apache.xerces.xni.XMLLocator;
import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.grammars.XMLGrammarPool;
import org.apache.xerces.xni.parser.XMLComponent;
import org.apache.xerces.xni.parser.XMLComponentManager;
import org.apache.xerces.xni.parser.XMLConfigurationException;
import org.apache.xerces.xni.parser.XMLDocumentFilter;
import org.apache.xerces.xni.parser.XMLDocumentSource;


public class XmlIDHandler implements XMLDocumentFilter, XMLComponent {
        
    // property identifier:  ValidationManager
    protected static final String VALIDATION_MANAGER =
        Constants.XERCES_PROPERTY_PREFIX + 
Constants.VALIDATION_MANAGER_PROPERTY;
    
    // updated during reset
    protected ValidationManager fValidationManager = null;
    
    // features

    /** Namespaces. */
    protected boolean fNamespaces;
    
    /** Validation. */
    protected boolean fValidation;

    /** Validation against only DTD */
    protected boolean fDTDValidation;   
  
       // XML document version
    private String version = "0";  
        
         /** Datatype validator: ID. */
        //protected DatatypeValidator fValID;
        protected IDDatatypeValidator fValID = new IDDatatypeValidator();
        
         // validation state
    protected final ValidationState fValidationState = new ValidationState();
    
    /** Error reporter. */
    protected XMLErrorReporter fErrorReporter;
    
    /** Temporary string buffers. */
    private final StringBuffer fBuffer = new StringBuffer();
    
    /** Temporary atribute declaration. */
    private final XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
    
    // handlers

    /** Document handler. */
    protected XMLDocumentHandler fDocumentHandler;

    protected XMLDocumentSource fDocumentSource;
    
    /** Current element index. */
    private int fCurrentElementIndex = -1;
    
    /** Datatype validator factory. */
    protected DTDDVFactory fDatatypeValidatorFactory;

        @Override
        public void characters(XMLString text, Augmentations augs)
                        throws XNIException {

                 // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.characters(text, augs);
        }
                
        }

        @Override
        public void comment(XMLString text, Augmentations augs) throws 
XNIException {
                
                // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.comment(text, augs);
        }
        }

        @Override
        public void doctypeDecl(String rootElement, String publicId, String 
systemId,
                        Augmentations augs) throws XNIException {
                
                 // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs);
        }
                
        }

        @Override
        public void emptyElement(QName element, XMLAttributes attributes, 
Augmentations augs)
                        throws XNIException {
                
                  if (fDocumentHandler !=null) {
                    fDocumentHandler.emptyElement(element, attributes, augs);
                }
                
        }

        @Override
        public void endCDATA(Augmentations augs) throws XNIException {
                
                 // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.endCDATA(augs);
        }
                
        }

        @Override
        public void endDocument(Augmentations augs) throws XNIException {
                
                 // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.endDocument(augs);
        }
                
        }

        @Override
        public void endElement(QName element, Augmentations augs) throws 
XNIException {
                
                // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.endElement(element,augs);
        }
        }

        @Override
        public void endGeneralEntity(String name, Augmentations augs)
                        throws XNIException {
                 // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.endGeneralEntity(name, augs);
        }
                
        }

        @Override
        public XMLDocumentSource getDocumentSource() {
                return fDocumentSource;
        }

        @Override
        public void ignorableWhitespace(XMLString text, Augmentations augs)
                        throws XNIException {
                
                // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.ignorableWhitespace(text, augs);
        }
                
        }

        @Override
        public void processingInstruction(String target, XMLString data,
                        Augmentations augs) throws XNIException {
                
                // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.processingInstruction(target, data, augs);
        }
                
        }

        @Override
        public void setDocumentSource(XMLDocumentSource source) {
                fDocumentSource = source;
                
        }

        @Override
        public void startCDATA(Augmentations augs) throws XNIException {
                
                // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.startCDATA(augs);
        }
                
        }

        @Override
        public void startDocument(XMLLocator locator, String encoding,
                        NamespaceContext namespaceContext, Augmentations augs) 
throws XNIException {
                
                if (fDocumentHandler != null) {
            fDocumentHandler.startDocument(locator, encoding, namespaceContext, 
augs);
        }
                
        }

        
        public void startElement(QName element, XMLAttributes attributes, 
Augmentations augs)
                        throws XNIException {
                System.out.println("xmlid handler");
                if (version.equals("1.1")){
                        if (attributes.getIndex("xml:id") == 0){
                                fCurrentElementIndex = 
attributes.getIndex("xml:id");
                        addXmlIDAttrsAndValidate(element, fCurrentElementIndex, 
attributes);
                }
                }
                
                
                // call handlers
                if (fDocumentHandler != null) {
                    fDocumentHandler.startElement(element, attributes, augs);

                }
                
        }

        @Override
        public void startGeneralEntity(String name, XMLResourceIdentifier 
identifier,
                        String encoding, Augmentations augs) throws 
XNIException {
                
                 if (fDocumentHandler != null) {
                    fDocumentHandler.startGeneralEntity(name, identifier, 
encoding, augs);
                }
                
        }

        @Override
        public void textDecl(String version, String encoding, Augmentations 
augs)
                        throws XNIException {
                // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.textDecl(version, encoding, augs);
        }
                
        }
        

        public void xmlDecl(String version, String encoding, String standalone, 
Augmentations augs)
    throws XNIException {
                
                if (version.equals("1.1")){
                        setVersion(version);
                        
                }
        // call handlers
        if (fDocumentHandler != null) {
            fDocumentHandler.xmlDecl(version, encoding, standalone, augs);
        }

    } // xmlDecl(String,String,String)

        private void setVersion(String version) {
                this.version = version;
                
        }

        @Override
        public XMLDocumentHandler getDocumentHandler() {                
                return fDocumentHandler;
        }

        @Override
        public void setDocumentHandler(XMLDocumentHandler documentHandler) {
                 fDocumentHandler = documentHandler;
                
        }
        
         /** Add xml:ids and validate. */
    protected void addXmlIDAttrsAndValidate(QName elementName, int 
elementIndex, 
                                               XMLAttributes attributes) {
        
        int attrCount = attributes.getLength();
        for (int i = 0; i < attrCount; i++) {
            String attrRawName = attributes.getQName(i);
            
            boolean changedByNormalization = false;
            String oldValue = attributes.getValue(i);
            String attrValue = oldValue;
            changedByNormalization = normalizeAttrValue(attributes, i);
            attrValue = attributes.getValue(i);
            
         // if ( fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ID ) 
         if ( true ) {
                 //c fTempAttDecl is not define
                    validateXmlIDAttribute(elementName, attrValue, 
fTempAttDecl);
                }
            
        }
        
        
    }

        private void validateXmlIDAttribute(QName element, String attValue,
                        XMLAttributeDecl attributeDecl) throws XNIException {
                configure();
                try {
            fValID.validate(attValue, fValidationState);
        }
        catch (InvalidDatatypeValueException ex) {
            fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                       ex.getKey(),
                                       ex.getArgs(),
                                       XMLErrorReporter.SEVERITY_ERROR );
        }
        }
        
    private void configure() {
         
             try {
                 //REVISIT: datatypeRegistry + initialization of datatype 
                 //         why do we cast to ListDatatypeValidator?
                 //fDatatypeValidatorFactory = 
(DTDDVFactory)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + 
Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY);
                        
                 //fValID       = 
fDatatypeValidatorFactory.getBuiltInDV(XMLSymbols.fIDSymbol);

             }
             catch (Exception e) {
                 // should never happen
                 e.printStackTrace(System.err);
             }

        
        }

        private boolean normalizeAttrValue(XMLAttributes attributes, int index) 
{
        
        // vars
        boolean leadingSpace = true;
        boolean spaceStart = false;
        boolean readingNonSpace = false;
        int count = 0;
        int eaten = 0;
        String attrValue = attributes.getValue(index);
        System.out.println(attrValue);
        char[] attValue = new char[attrValue.length()];

        fBuffer.setLength(0);
        attrValue.getChars(0, attrValue.length(), attValue, 0);
        for (int i = 0; i < attValue.length; i++) {

            if (attValue[i] == ' ') {

                // now the tricky part
                if (readingNonSpace) {
                    spaceStart = true;
                    readingNonSpace = false;
                }

                if (spaceStart && !leadingSpace) {
                    spaceStart = false;
                    fBuffer.append(attValue[i]);
                    count++;
                }
                else {
                    if (leadingSpace || !spaceStart) {
                        eaten ++;
                        /*** BUG #3512 ***
                        int entityCount = attributes.getEntityCount(index);
                        for (int j = 0;  j < entityCount; j++) {
                            int offset = attributes.getEntityOffset(index, j);
                            int length = attributes.getEntityLength(index, j);
                            if (offset <= i-eaten+1) {
                                if (offset+length >= i-eaten+1) {
                                    if (length > 0)
                                        length--;
                                }
                            } 
                            else {
                                if (offset > 0)
                                    offset--;
                            }
                            attributes.setEntityOffset(index, j, offset);
                            attributes.setEntityLength(index, j, length);
                        }
                        /***/
                    }
                }

            }
            else {
                readingNonSpace = true;
                spaceStart = false;
                leadingSpace = false;
                fBuffer.append(attValue[i]);
                count++;
            }
        }

        // check if the last appended character is a space.
        if (count > 0 && fBuffer.charAt(count-1) == ' ') {
            fBuffer.setLength(count-1);
            /*** BUG #3512 ***
            int entityCount = attributes.getEntityCount(index);
            for (int j=0;  j < entityCount; j++) {
                int offset = attributes.getEntityOffset(index, j);
                int length = attributes.getEntityLength(index, j);
                if (offset < count-1) {
                    if (offset+length == count) {
                        length--;
                    }
                } 
                else {
                    offset--;
                }
                attributes.setEntityOffset(index, j, offset);
                attributes.setEntityLength(index, j, length);
            }
            /***/
        }
        String newValue = fBuffer.toString();
        attributes.setValue(index, newValue);
        return ! attrValue.equals(newValue);
    }

        @Override
        public Boolean getFeatureDefault(String featureId) {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public Object getPropertyDefault(String propertyId) {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public String[] getRecognizedFeatures() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public String[] getRecognizedProperties() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public void reset(XMLComponentManager componentManager)
                        throws XMLConfigurationException {

        fCurrentElementIndex = -1;
        

                fValidationState.resetIDTables();
            
 

        fValidationManager= 
(ValidationManager)componentManager.getProperty(VALIDATION_MANAGER);
        fValidationManager.addValidationState(fValidationState);      
        fValidationState.setUsingNamespaces(fNamespaces);
        
        // get needed components
        fErrorReporter = 
(XMLErrorReporter)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.ERROR_REPORTER_PROPERTY);
       
    
                
        }

        @Override
        public void setFeature(String featureId, boolean state)
                        throws XMLConfigurationException {
                // TODO Auto-generated method stub
                
        }

        @Override
        public void setProperty(String propertyId, Object value)
                        throws XMLConfigurationException {
                // TODO Auto-generated method stub
                
        }

}


> [GSoC]: Support for xml:id
> --------------------------
>
>                 Key: XERCESJ-1113
>                 URL: https://issues.apache.org/jira/browse/XERCESJ-1113
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: XInclude 1.0
>    Affects Versions: 2.7.1
>         Environment: All
>            Reporter: George Cristian Bina
>              Labels: gsoc2011
>
> Hi,
> The XInclude ID support should handle xml:id. This is useful for instance 
> with DocBook or TEI that use Relax NG schemas for validation and also need 
> XInclude support.
> Here it is a patch that adds support for handling xml:id attributes as 
> attributes of ID type.
> Index: 
> C:/george/workspace/xerces/src/org/apache/xerces/xpointer/ShortHandPointer.java
> ===================================================================
> --- 
> C:/george/workspace/xerces/src/org/apache/xerces/xpointer/ShortHandPointer.java
>    (revision 344362)
> +++ 
> C:/george/workspace/xerces/src/org/apache/xerces/xpointer/ShortHandPointer.java
>    (working copy)
> @@ -162,6 +162,17 @@
>              }
>          }
>          
> +        if (normalizedValue == null && attributes != null) {
> +             // Try to see if we can get an xml:id
> +             for (int i = 0; i < attributes.getLength(); i++) {
> +                     if ("xml".equals(attributes.getPrefix(i)) && 
> +                                     
> "id".equals(attributes.getLocalName(i))) {
> +                             normalizedValue = attributes.getValue(i);
> +                             break;
> +                     }
> +             }               
> +        }
> +        
>          if (normalizedValue != null
>                  && normalizedValue.equals(fShortHandPointer)) {
>              return true;
> Best Regards,
> George

--
This message is automatically generated by JIRA.
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