Using 'Import' rather than 'Include' in IAB Schemas

Mar 15, 2010 at 4:54 PM

To our understanding XML Schema doesn't allow an element to be defined more than once for a namespace.  For example, this occurs when IAB_Proposal,xsd is parsed because it includes both IAB_OrderCommon.xsd  and IAB_ContractCommon.xsd , which both include IAB_BillingCommon.  Our XML parser raises an error when this happens.

Has anyone else come across this issue?

Can we should consider changing the IAB RFP and IAB Proposal schemas to utilize 'import' rather than 'include' for these cases.

Thanks,

Sandy

 

 

Mar 16, 2010 at 5:18 PM

Hi Sandy,

            Even we came across from the same issue. After we change our validation code block then it starts working. And I believe xsd:include is the right keyword rather than xsd:import .

 Here is the link: http://msdn.microsoft.com/en-us/library/ms256198(VS.80).aspx

 Thanks,

Rao

Mar 16, 2010 at 5:54 PM

Hello Rao,

Can you please supply additional details on what you did for it to start working?

Also what I meant by using import rather than include is to define some of the commonly reused schemas in separate namespaces and import those schemas.

This would resolve the issue of elements being defined more than once for schemas that are potentially recursively reused.

Thanks,

Sandy

 

 

Mar 22, 2010 at 7:46 PM

Hi Sandy, Do you fix this issue? Or else if you are planning to change the schemas from include to import? Can you provide us the modified XSD schema's (i.e. include to import)?
Thanks, Rao

Mar 23, 2010 at 2:37 PM

Hi Rao -

We have a work around for this but also wanted to see if there is a better solution. 

Will from Solbright is testing changing the order of the include statements in the schema and seeing if that makes a difference. 

This may just be a problem with the specific Java parser/validator that we are using.  If so we'll need to handle it and not require any changes to the IAB schemas.

Thanks,

Sandy

 

Mar 23, 2010 at 11:50 PM

As mentioned before, I'm attaching some sample code related to how we do XML-to-XSD validations. Here are some points to note.

  • There are 4 main documents to validate: RFP, IO, Proposal and ACK
  • The validator we used is from the JDK (1.5, 1.6) - javax.xml.validation.Validator
  • Because most of the 4 main documents share common data complex types and the JDK could not validate the different documents with the same Validator, we had to create 4 different Validators; one validator per main document
  • Based on the payload, we chose the correlating Validator and validated the payload against the schema

Here are the code snippets. I hope you can follow along.

   private void initialize() {
	   // initializing for Acknowledgement messages
	   String key;
	   IABDocument docType;
	   String[] schemaLocations = {
			   "xsd/IAB_Acknowledgement.xsd",
			   "xsd/IAB_Common.xsd"
	   };
	   
	   docType = new IABDocument(IABMessageType.ACKNOWLEDGEMENT, 
			   "Acknowledgement", IAB_NAMESPACE_URI);
	   BasicDocumentValidator docValidator = new BasicDocumentValidator(docType, schemaLocations);
	   key = determineDocumentKey(docType);
	   schemaValidators.put(key, docValidator);
	   
	   // initializing for RFP messages
	   schemaLocations = new String[] {
			   "xsd/IAB_RFPCommon.xsd",
				   "xsd/IAB_MessageCommon.xsd",
					   "xsd/IAB_CampaignCommon.xsd",
						   "xsd/IAB_Common.xsd",
					   "xsd/IAB_AdvertiserCommon.xsd",
					   "xsd/IAB_PublisherCommon.xsd",
				   "xsd/IAB_ContractCommon.xsd",
					   "xsd/IAB_BillingCommon.xsd"
	   };	
	   docType = new IABDocument(IABMessageType.RFP, 
			   "RequestForProposal", IAB_NAMESPACE_URI);
	   docValidator = new BasicDocumentValidator(docType, schemaLocations);
	   key = determineDocumentKey(docType);
	   schemaValidators.put(key, docValidator);
	   
	   // initializing for Proposal messages
	   schemaLocations = new String[] {
			   "xsd/IAB_ProposalCommon.xsd",
				   "xsd/IAB_MessageCommon.xsd",
					   "xsd/IAB_CampaignCommon.xsd",
						   "xsd/IAB_Common.xsd",
					   "xsd/IAB_AdvertiserCommon.xsd",
					   "xsd/IAB_PublisherCommon.xsd",
				   "xsd/IAB_ContractCommon.xsd",
					   "xsd/IAB_BillingCommon.xsd",
				   "xsd/IAB_OrderCommon.xsd",
					   "xsd/IAB_LineItemCommon.xsd",
	   };	
	   docType = new IABDocument(IABMessageType.PROPOSAL, 
			   "Proposal", IAB_NAMESPACE_URI);
	   docValidator = new BasicDocumentValidator(docType, schemaLocations);
	   key = determineDocumentKey(docType);
	   schemaValidators.put(key, docValidator);

	   // initializing for IO messages
	   schemaLocations = new String[] {
			   "xsd/IAB_InsertionOrderCommon.xsd",
				   "xsd/IAB_ContractCommon.xsd",
					   "xsd/IAB_BillingCommon.xsd",
						   "xsd/IAB_Common.xsd",
				   "xsd/IAB_OrderCommon.xsd",
					   "xsd/IAB_LineItemCommon.xsd",
				   "xsd/IAB_MessageCommon.xsd",
					   "xsd/IAB_CampaignCommon.xsd",
					   "xsd/IAB_AdvertiserCommon.xsd",
					   "xsd/IAB_PublisherCommon.xsd",
	   };	
	   docType = new IABDocument(IABMessageType.IO, 
			   "InsertionOrder", IAB_NAMESPACE_URI);
	   docValidator = new BasicDocumentValidator(docType, schemaLocations);
	   key = determineDocumentKey(docType);
	   schemaValidators.put(key, docValidator);
	   
   }


And this is how we built our Validators, each based on the 4 main documents:
public class BasicDocumentValidator{

...
	public BasicDocumentValidator(IABDocument iabDocumentType, String[] schemaLocations) {
		if (iabDocumentType == null) {
			throw new IllegalArgumentException(
					"IABDocument argument of BasicDocumentValidator cannot be null.");
		}
		if ( (schemaLocations == null) || (schemaLocations.length == 0) ) {
			throw new IllegalArgumentException(
					"No schemas added for validation.");			
		}
		this.iabDocumentType = iabDocumentType;
		this.schemaLocations = schemaLocations;
		initialize();
	}
	
	private void initialize() {
		Source[] allSchemaSources = getSourcesFromLocations(schemaLocations);
		
		try {
			Schema schema = schemaFactory.newSchema(allSchemaSources);
			validator = schema.newValidator();
		} catch (SAXException e) {
			throw new DocumentValidatorException("Failed to initialize SchemaValidator filter", e);
		} 
	}	
	
	private static Source[] getSourcesFromLocations(String[] schemaLocations) {
		Source[] arrInputStreams = null;
		URL url = null;
		File file = new File(".");
		logger.debug("Current directory: " + file.getAbsolutePath());
		arrInputStreams = new Source[schemaLocations.length];
		for (int index = 0; index < schemaLocations.length; index++) { 
			String location = schemaLocations[index];
			url = Thread.currentThread().getContextClassLoader().getResource(location);
			logger.debug("resource url: " + url.toExternalForm());
			arrInputStreams[index] = new StreamSource(url.toExternalForm());
		}
		return arrInputStreams;
	}

...
}