This one is definitely in the "use at your own risk" category. I needed the
capability for an XML document to be validated from a
Schema AND include short fragments. Currently you can have a DOCTYPE with an
internal DTD and ENTITY definitions OR you can
validate from a Schema, but not both. I got fed up with trying to sort through
XLink, XPointer, XFragment, XPath, the XSchema 12/17
draft, and the rest of the XYouGottaBeKiddings so I took the brute force
approach and patched XMLParser.java to get external
entities from an internal DTD subset but still validate the rest of the
document (and the included entities) against a Schema.
<!DOCTYPE document
[
<!ENTITY abc SYSTEM "abc.xml">
]>
<document xmlns="doc.xsd">
...
&abc;
...
</document>
The patch to XMLParser.java works for me and is certainly not long-term but I
would have otherwise had to scrap Schemas in my
project and write a ton of custom validation code to supplement the DTD. I've
been looking at XMLParser for only a few hours (and
it's now 3AM) so if anyone sees problems in the appended diff or can point out
alternatives I might have missed, I'd be glad to hear
about them.
George
***************************************
*** XMLParserOrig.java Wed Jan 05 15:12:16 2000
--- XMLParser.java Fri Jan 07 01:04:08 2000
***************
*** 2005,2011 ****
/** Scan doctype decl. */
public void scanDoctypeDecl(boolean standalone) throws Exception {
fScanningDTD = true;
! fCheckedForSchema = true;
fStandaloneDocument = standalone;
fValidator = fDTDValidator;
fDTDValidator.scanDoctypeDecl(standalone);
--- 2005,2011 ----
/** Scan doctype decl. */
public void scanDoctypeDecl(boolean standalone) throws Exception {
fScanningDTD = true;
! // fCheckedForSchema = true;
fStandaloneDocument = standalone;
fValidator = fDTDValidator;
fDTDValidator.scanDoctypeDecl(standalone);
***************
*** 2413,2419 ****
public boolean startReadingFromEntity(int entityName, int readerDepth,
int context) throws Exception {
if (context > XMLEntityHandler.CONTEXT_IN_CONTENT)
return startReadingFromParameterEntity(entityName, readerDepth,
context);
! int entityHandle = fValidator.lookupEntity(entityName);
if (entityHandle < 0) {
int minorCode = XMLMessages.VC_ENTITY_DECLARED;
int errorType = XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR;
--- 2413,2419 ----
public boolean startReadingFromEntity(int entityName, int readerDepth,
int context) throws Exception {
if (context > XMLEntityHandler.CONTEXT_IN_CONTENT)
return startReadingFromParameterEntity(entityName, readerDepth,
context);
! int entityHandle = fDTDValidator.lookupEntity(entityName);
if (entityHandle < 0) {
int minorCode = XMLMessages.VC_ENTITY_DECLARED;
int errorType = XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR;
***************
*** 2432,2438 ****
return false;
}
if (context == CONTEXT_IN_CONTENT) {
! if (fValidator.isUnparsedEntity(entityHandle)) {
Object[] args = { fStringPool.toString(entityName) };
fErrorReporter.reportError(fErrorReporter.getLocator(),
XMLMessages.XML_DOMAIN,
--- 2432,2438 ----
return false;
}
if (context == CONTEXT_IN_CONTENT) {
! if (fDTDValidator.isUnparsedEntity(entityHandle)) {
Object[] args = { fStringPool.toString(entityName) };
fErrorReporter.reportError(fErrorReporter.getLocator(),
XMLMessages.XML_DOMAIN,
***************
*** 2443,2449 ****
return false;
}
} else {
! if (fValidator.isExternalEntity(entityHandle)) {
Object[] args = { fStringPool.toString(entityName) };
fErrorReporter.reportError(fErrorReporter.getLocator(),
XMLMessages.XML_DOMAIN,
--- 2443,2449 ----
return false;
}
} else {
! if (fDTDValidator.isExternalEntity(entityHandle)) {
Object[] args = { fStringPool.toString(entityName) };
fErrorReporter.reportError(fErrorReporter.getLocator(),
XMLMessages.XML_DOMAIN,
***************
*** 2470,2490 ****
fEntityContext = context;
fReaderDepth = readerDepth;
fReaderId = fNextReaderId++;
! if (context != CONTEXT_IN_CONTENT ||
!fValidator.externalReferenceInContent(entityHandle)) {
fEntityType = ENTITYTYPE_INTERNAL;
fPublicId = null/*"Internal Entity: " +
fStringPool.toString(entityName)*/;
fSystemId = fSystemId; // keep expandSystemId happy
int value = -1;
if (context == CONTEXT_IN_CONTENT || context ==
CONTEXT_IN_DEFAULTATTVALUE)
! value = fValidator.getEntityValue(entityHandle);
else
! value = fValidator.valueOfReferenceInAttValue(entityHandle);
startReadingFromInternalEntity(value, false);
return false;
}
fEntityType = ENTITYTYPE_EXTERNAL;
! fPublicId = fValidator.getPublicIdOfEntity(entityHandle);
! fSystemId = fValidator.getSystemIdOfEntity(entityHandle);
return startReadingFromExternalEntity(true);
}
private boolean startReadingFromParameterEntity(int peName, int
readerDepth, int context) throws Exception {
--- 2470,2490 ----
fEntityContext = context;
fReaderDepth = readerDepth;
fReaderId = fNextReaderId++;
! if (context != CONTEXT_IN_CONTENT ||
!fDTDValidator.externalReferenceInContent(entityHandle)) {
fEntityType = ENTITYTYPE_INTERNAL;
fPublicId = null/*"Internal Entity: " +
fStringPool.toString(entityName)*/;
fSystemId = fSystemId; // keep expandSystemId happy
int value = -1;
if (context == CONTEXT_IN_CONTENT || context ==
CONTEXT_IN_DEFAULTATTVALUE)
! value = fDTDValidator.getEntityValue(entityHandle);
else
! value =
fDTDValidator.valueOfReferenceInAttValue(entityHandle);
startReadingFromInternalEntity(value, false);
return false;
}
fEntityType = ENTITYTYPE_EXTERNAL;
! fPublicId = fDTDValidator.getPublicIdOfEntity(entityHandle);
! fSystemId = fDTDValidator.getSystemIdOfEntity(entityHandle);
return startReadingFromExternalEntity(true);
}
private boolean startReadingFromParameterEntity(int peName, int
readerDepth, int context) throws Exception {