You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by "Ishara Karunarathna (JIRA)" <xe...@xml.apache.org> on 2011/06/29 05:11:28 UTC
[jira] [Commented] (XERCESJ-1113) [GSoC]: Support for xml:id
[ 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: j-dev-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-dev-help@xerces.apache.org