Jump to content

Finding the root element of an XSD schema file.


sanket_das1

Recommended Posts

I have an XSD that is valid but the code in my application is unable to parse the schema as it is unable to locate the root element. We use DOM parser to validate the XSD. However it is not parsing our XSD if the first elemt is not the root elemnt.I think our problem lies in detecting the root elemt.Can you help us getting any API call or something which could help us parse the SChema. If DOM parser cannot be applicable, we can also implement the SAX parser.Please post ASAP as we have delivery deadlines.Thanks in advance

Link to comment
Share on other sites

Hi all,I would also like to add the XSD sample for your refernce.PLEASE NOTE THE FIRST ELEMENT "homeOwner" in our XSD. This is being treated as root./**************************************************************************************************/<xsd:element name="homeOwner" type="xsd:boolean" minOccurs="0"/> <xsd:element name="propertyValue" type="xsd:double" minOccurs="0"> <xsd:annotation><xsd:documentation xml:lang="en"> Value of present property </xsd:documentation></xsd:annotation> </xsd:element> <xsd:element name="accType" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="accountCode" type="xsd:string"/> <xsd:element name="accountDescription" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element>/*************************************************************************************************/THE ACTUAL ROOT ELEMENT IS "production" which is MUCH BELOW IN THE XSD AS:/*************************************************************************************************//*************************************************************************************************/<xsd:element name="production"> <xsd:annotation><xsd:documentation xml:lang="en"> Contains all the documents to be printed. numDocs should correspond to the number of documentStart tags </xsd:documentation></xsd:annotation> <xsd:complexType> <xsd:sequence> <xsd:element name="appControl" type="xsd:string" minOccurs="0" maxOccurs="unbounded"> <xsd:annotation><xsd:documentation xml:lang="en"> Low-level commands to the printing server </xsd:documentation></xsd:annotation> </xsd:element> <xsd:element name="publicationStart" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="publicationData" type="goip:publicationDataType"/> <xsd:element name="customer" type="goip:customerType"/> <xsd:element name="documentContent" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="originator" type="goip:originatorType" minOccurs="0"/> <xsd:element name="accountFinancial" type="goip:accountFinancialType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="facilityFinancial" type="goip:facilityFinancialType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="interestFinancial" type="goip:interestFinancialType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="chargesFinancial" type="goip:chargesFinancialType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="interestRates" type="goip:interestRatesType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="creditCardInterestRates" type="goip:creditCardInterestRatesType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="transaction" type="goip:transactionType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="plan" type="goip:planType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="transfer" type="goip:transferType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="customerAccOpen" type="goip:accountOpenType" minOccurs="0"> <xsd:annotation><xsd:documentation xml:lang="en"> Contains details relating to the opening of a customers account </xsd:documentation></xsd:annotation> </xsd:element> <xsd:element name="jointAccOpen" type="goip:accountOpenType" minOccurs="0"> <xsd:annotation><xsd:documentation xml:lang="en"> Contains details relating to the opening of a joint customers account </xsd:documentation></xsd:annotation> </xsd:element> <xsd:element name="currencyConversion" type="goip:currencyConversionType" minOccurs="0"/> <xsd:element name="general" type="goip:generalType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="table" type="goip:tableType" minOccurs="0" maxOccurs="unbounded"/> <xsd:element name="comment" type="xsd:string" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="documentName" use="required"> <xsd:simpleType> <xsd:annotation><xsd:documentation xml:lang="en"> Indicates which Document Set is expected to be built. The Composition engine would then use pre-defined scripts to produce the expected document set. The composition engine should, as far as possible, use common code developed for the generic interface to carry out this function. This name is defined and agreed between the application developer and the composition developer. Expected to be an ten-byte filename format field. </xsd:documentation></xsd:annotation> <xsd:restriction base="xsd:string"> <xsd:length value="8"/> </xsd:restriction> </xsd:simpleType> </xsd:attribute> <xsd:attribute name="documentType"> <xsd:simpleType> <xsd:annotation><xsd:documentation xml:lang="en"> Allows further identification of the Document to be produced. Expected to be an eight-byte filename format field. </xsd:documentation></xsd:annotation> <xsd:restriction base="xsd:string"> <xsd:length value="8"/> </xsd:restriction> </xsd:simpleType> </xsd:attribute> </xsd:complexType> </xsd:element>/***********************************************************************************************/So can you guys provide any clues to parse this XSD.

Link to comment
Share on other sites

So what validator exactly are you using for validation? How are you using it?Any sample tentatevely valid XML file I could try to validate myself?How about moving the root element to the top?

Link to comment
Share on other sites

So what validator exactly are you using for validation? How are you using it?Any sample tentatevely valid XML file I could try to validate myself?How about moving the root element to the top?
First is we are not using an XML, but the XSD format I have posted earlier. We cannot change the XSD as it is a valid one.2ndly I am noting dowm\n some code snippet that we use for parsing schema files. Kindly go through it and post your suggestions:CString CSaTfXSrc::ParseXMLSchemaFile( const CString & sDoc ){ CString sErr; try { DOMParser parser; // Setup the rules we want the parser to use // parser.setValidationScheme(DOMParser::Val_Always); parser.setDoNamespaces(true); parser.setDoSchema(true); SchemaGrammar* grammar = (SchemaGrammar*)parser.loadGrammar(sDoc, Grammar::SchemaGrammarType, true); RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator(); // There should be root elements. if(elemEnum.hasMoreElements() == 0 ) { sErr.Format( "Error parsing error" ); return( sErr ); } elemEnum.Reset(); //Instead of passing Grammar, we now pass the element enumerator ParseXMLElement( elemEnum, "", NULL ); } catch (const XMLException& toCatch) { char* pMsg = XMLString::transcode( toCatch.getMessage() ); sErr.Format( "Error parsing error: \n\t%s", pMsg ); XMLString::release( &pMsg ); } catch (const DOM_DOMException& toCatch) { sErr.Format( "Error parsing error: \n\t%d", toCatch.code ); } catch (...) { sErr.Format( "Error parsing error" ); } return( sErr );}Plz find below the method ParseXMLElement that is being used above./*************************************************************/void CSaTfXSrc::ParseXMLElement(RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum, CString eleName, CSaXMLField* pParentField){ while( elemEnum.hasMoreElements() ) { SchemaElementDecl& curElem = elemEnum.nextElement(); char * ptchar = XMLString::transcode(curElem.getFullName()); CString curName = (LPCTSTR) ptchar; XMLString::release( &ptchar ); if( eleName.IsEmpty() || !curName.CompareNoCase(eleName) ) { // find XML element //At first check the registered element CSaXMLField *pField = FindChildElementByName( pParentField, curName ); if( pField == NULL ) { const DatatypeValidator* dV = curElem.getDatatypeValidator(); SADC_DATA_TYPE SagentSchemaType = CheckXMLSchemaType(dV); pField = new CSaXMLField( curName, pParentField, pParentField?TRUE:FALSE, FALSE, pParentField?0:1, FALSE, SagentSchemaType, 20, 0, NULL ); if( !pParentField ) { if( m_pRootElement ) delete m_pRootElement; m_pRootElement = pField; } else pParentField->m_ChildElements.Add( pField ); } // process attribute if ( curElem.hasAttDefs() ) { XMLAttDefList& attList = curElem.getAttDefList(); if( attList.isEmpty() == false ) { while( attList.hasMoreElements() ) { SchemaAttDef& curAttDef = (SchemaAttDef&)attList.nextElement(); ptchar = XMLString::transcode(curAttDef.getFullName()); CString curAtName = ptchar; XMLString::release( &ptchar ); if( !FindChildElementByName( pField, curAtName ) ) { CSaXMLField *pAttribField; const DatatypeValidator* dv = curAttDef.getDatatypeValidator(); SADC_DATA_TYPE SagentSchemaType = CheckXMLSchemaType(dv); pAttribField = new CSaXMLField( curAtName, pField, TRUE, FALSE, 1, TRUE, SagentSchemaType, 128, 0, NULL ); pField->m_ChildElements.Add( pAttribField ); } } } } // check the children element ptchar = XMLString::transcode(curElem.getFormattedContentModel()); CString sCntMdl = (LPCTSTR) ptchar; XMLString::release( &ptchar ); if( !sCntMdl.IsEmpty() ) { // There is at least one child element CCntMdlEnum eMdl(sCntMdl); while( eMdl.HasMoreElement() ) { CString sChildElement = eMdl.GetNextElement(); //Changed the first parameter from Grammar to element enumerator ParseXMLElement(elemEnum, sChildElement, pField); //Infosys: Ends } // while } return; }// if }// while }// functionI can send you the XSD sample also provided you can give me the mail id.Need your help . Thanks
Link to comment
Share on other sites

First is we are not using an XML, but the XSD format I have posted earlier. We cannot change the XSD as it is a valid one.2ndly I am noting dowm\n some code snippet that we use for parsing schema files. Kindly go through it and post your suggestions:CString CSaTfXSrc::ParseXMLSchemaFile( const CString & sDoc ){ CString sErr; try { DOMParser parser; // Setup the rules we want the parser to use // parser.setValidationScheme(DOMParser::Val_Always); parser.setDoNamespaces(true); parser.setDoSchema(true); SchemaGrammar* grammar = (SchemaGrammar*)parser.loadGrammar(sDoc, Grammar::SchemaGrammarType, true); RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator(); // There should be root elements. if(elemEnum.hasMoreElements() == 0 ) { sErr.Format( "Error parsing error" ); return( sErr ); } elemEnum.Reset(); //Instead of passing Grammar, we now pass the element enumerator ParseXMLElement( elemEnum, "", NULL ); } catch (const XMLException& toCatch) { char* pMsg = XMLString::transcode( toCatch.getMessage() ); sErr.Format( "Error parsing error: \n\t%s", pMsg ); XMLString::release( &pMsg ); } catch (const DOM_DOMException& toCatch) { sErr.Format( "Error parsing error: \n\t%d", toCatch.code ); } catch (...) { sErr.Format( "Error parsing error" ); } return( sErr );}Plz find below the method ParseXMLElement that is being used above./*************************************************************/void CSaTfXSrc::ParseXMLElement(RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum, CString eleName, CSaXMLField* pParentField){ while( elemEnum.hasMoreElements() ) { SchemaElementDecl& curElem = elemEnum.nextElement(); char * ptchar = XMLString::transcode(curElem.getFullName()); CString curName = (LPCTSTR) ptchar; XMLString::release( &ptchar ); if( eleName.IsEmpty() || !curName.CompareNoCase(eleName) ) { // find XML element //At first check the registered element CSaXMLField *pField = FindChildElementByName( pParentField, curName ); if( pField == NULL ) { const DatatypeValidator* dV = curElem.getDatatypeValidator(); SADC_DATA_TYPE SagentSchemaType = CheckXMLSchemaType(dV); pField = new CSaXMLField( curName, pParentField, pParentField?TRUE:FALSE, FALSE, pParentField?0:1, FALSE, SagentSchemaType, 20, 0, NULL ); if( !pParentField ) { if( m_pRootElement ) delete m_pRootElement; m_pRootElement = pField; } else pParentField->m_ChildElements.Add( pField ); } // process attribute if ( curElem.hasAttDefs() ) { XMLAttDefList& attList = curElem.getAttDefList(); if( attList.isEmpty() == false ) { while( attList.hasMoreElements() ) { SchemaAttDef& curAttDef = (SchemaAttDef&)attList.nextElement(); ptchar = XMLString::transcode(curAttDef.getFullName()); CString curAtName = ptchar; XMLString::release( &ptchar ); if( !FindChildElementByName( pField, curAtName ) ) { CSaXMLField *pAttribField; const DatatypeValidator* dv = curAttDef.getDatatypeValidator(); SADC_DATA_TYPE SagentSchemaType = CheckXMLSchemaType(dv); pAttribField = new CSaXMLField( curAtName, pField, TRUE, FALSE, 1, TRUE, SagentSchemaType, 128, 0, NULL ); pField->m_ChildElements.Add( pAttribField ); } } } } // check the children element ptchar = XMLString::transcode(curElem.getFormattedContentModel()); CString sCntMdl = (LPCTSTR) ptchar; XMLString::release( &ptchar ); if( !sCntMdl.IsEmpty() ) { // There is at least one child element CCntMdlEnum eMdl(sCntMdl); while( eMdl.HasMoreElement() ) { CString sChildElement = eMdl.GetNextElement(); //Changed the first parameter from Grammar to element enumerator ParseXMLElement(elemEnum, sChildElement, pField); //Infosys: Ends } // while } return; }// if }// while }// functionI can send you the XSD sample also provided you can give me the mail id.Need your help . Thanks
Also need to know if there r any special .h(header) files that we need to include for this purpose. We have complete access to the Xersec DOM parser library files but some how we are unable to use methods like children.GetFirstXMLChild() and GetChildren() .
Link to comment
Share on other sites

First is we are not using an XML, but the XSD format I have posted earlier. We cannot change the XSD as it is a valid one.
What are you talking about? XML Schema (a.k.a. XSD) is used to validate XML based documents. What I'm asking you is if you could give me sample XML document that this schema would report as "valid" and another that is not supposed to be valid, yet when validated with the above schema, it's reported as "valid", rather then "invalid".
Link to comment
Share on other sites

  • 4 weeks later...

Hi Robot,I want 2 parse an XSD and not validate an XML against the XSD. I want to get to the root element of this XSD. My XSd is "Using Named Type" XSD. Please note the sample below:I have taken it from W3 forum. See thst here my application is detecting "name" as the root where as theactual root is "shiporder". I hope u got me this time. thanks.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<?xml version="1.0" encoding="ISO-8859-1" ?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:simpleType name="stringtype"> <xs:restriction base="xs:string"/></xs:simpleType><xs:simpleType name="inttype"> <xs:restriction base="xs:positiveInteger"/></xs:simpleType><xs:simpleType name="dectype"> <xs:restriction base="xs:decimal"/></xs:simpleType><xs:simpleType name="orderidtype"> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction></xs:simpleType><xs:complexType name="shiptotype"> <xs:sequence> <xs:element name="name" type="stringtype"/> <xs:element name="address" type="stringtype"/> <xs:element name="city" type="stringtype"/> <xs:element name="country" type="stringtype"/> </xs:sequence></xs:complexType><xs:complexType name="itemtype"> <xs:sequence> <xs:element name="title" type="stringtype"/> <xs:element name="note" type="stringtype" minOccurs="0"/> <xs:element name="quantity" type="inttype"/> <xs:element name="price" type="dectype"/> </xs:sequence></xs:complexType><xs:complexType name="shipordertype"> <xs:sequence> <xs:element name="orderperson" type="stringtype"/> <xs:element name="shipto" type="shiptotype"/> <xs:element name="item" maxOccurs="unbounded" type="itemtype"/> </xs:sequence> <xs:attribute name="orderid" type="orderidtype" use="required"/></xs:complexType><xs:element name="shiporder" type="shipordertype"/></xs:schema>

Link to comment
Share on other sites

Ah, I get it. Well, in that case, I believe what you need to find out is actually whether each element is being referenced anywhere within the schema. I beleve the only case where that won't be applicable is if the schema is completely recursive (somewhere in the root element, that root element references itself) and I'm not even sure if that't valid in Schema 1.0 to begin with.How you do that is very language dependant. In XSLT, iI think it will have something to do with keys... I'll have to investigate further, but even that, that might not help you, unless you'll be willing to run a whole transformation just for a single result.

Link to comment
Share on other sites

Hi Robot,Thanks for ur reply. I have another query .... Is there a way, so that I can convert the XSD in this format to the usual frmat and then may be parse it properly.Also if you can help me with some code snippets ...after your research it would be help full

Link to comment
Share on other sites

Is there a way, so that I can convert the XSD in this format to the usual frmat and then may be parse it properly.
Depends on what you mean by "usual". You can use XSLT to convert this or any XML based file to any other format you'd like, but scince schema is a standart, I don't really see how/why you'll do such a thing.
Also if you can help me with some code snippets ...after your research it would be help full
Well, you need to compare each node from
//xs:element/@name

against each node from

//xs:element/@ref

and see which @name is not present between the @ref attributes. As I said, that node should almost always be the root element of a schema.I'm not sure how to do that in XSLT and I have no clue how to do it in another language.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...