下面是测试用例:
//从schema文件和xml文件反序列化成一个SDO对象 DataObjectPtr generateSDOFromFile(const char* xsdFileUri, const char* xmlFileUri,const char* nameSpace = "") { DataObjectPtr root=NULL; try { DataFactoryPtr mdg=DataFactory::getDataFactory(); XSDHelperPtr xsdHelper=HelperProvider::getXSDHelper(mdg); string rootTypeURI = xsdHelper->defineFile(xsdFileUri); XMLHelperPtr xmlHelper = HelperProvider::getXMLHelper(mdg); XMLDocumentPtr xmlDoc=xmlHelper->loadFile(xmlFileUri,nameSpace); root=xmlDoc->getRootDataObject(); } catch(SDORuntimeException e) { cout << "Exception in generateSDOFromFile"<< endl; } catch(…) { cout<<”…Exception in generateSDOFromFile”<<endl; } return root; } void testSDOXsdBug() { DataObjectPtr company = generateSDOFromFile("company2.xsd", "company2.xml"); cout<<"aname = "<<company->getCString("aname")<<endl; cout<<"ename = "<<company->getCString("ename")<<endl; generateXsdFile(company, "generatedCompany2.xsd");//使用未更正的tuscany_sdo.dll 与company2.xsd不一致 anme属性变成了aname元素 generateXmlFile(company, "generatedCompany2.xml", "company");//与company2.xml一致 } //从SDO对象中构造schema文件 void generateXsdFile(DataObjectPtr dataObject,const char* xsdFileUri, const char* targetNamespace = "") { try { DataFactoryPtr mdg = DataFactory::getDataFactory(); mdg = dataObject->getDataFactory(); XSDHelperPtr xsdHelper = HelperProvider::getXSDHelper(mdg); TypeList tList = mdg->getTypes( ); cout<<"generateXsdFile: before generateFile"<<endl; xsdHelper->generateFile(tList,xsdFileUri,targetNamespace); cout<<"generateXsdFile: before generateFile"<<endl; } catch(SDORuntimeException e) { cout<<"Exception in generateXsdFile "<< endl; cout<< e<<endl; } catch(…) { cout<<"…Exception in generateXsdFile "<< endl; } } //-------------company2.xsd /* <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="company"> <xs:complexType> <xs:sequence> <xs:element name="ename" type="xs:string"/> </xs:sequence> <xs:attribute name="aname" type="xs:string"/> </xs:complexType> </xs:element> </xs:schema> */ //-------------generatedCompany2.xsd (使用原始的tuscany_sdo.dll) /* <xsd:schema xmlns:sdo="commonj.sdo" xmlns:sdoxml="commonj.sdo/xml" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="company" type="company"/> <xsd:complexType name="company"> <xsd:sequence> <xsd:element name="ename" type="xsd:String" minOccurs="0"/> <xsd:element name="aname" type="xsd:String" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:schema> */ //----------company2.xml /* <?xml version="1.0" encoding="UTF-8"?> <company aname = "aname"> <ename>ename</ename> </company> */ //----------generatedCompany2.xml /* <?xml version="1.0" encoding="UTF-8"?> <company xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" aname="aname"> <ename>ename</ename> </company> */
3.4 解决方案
前后两个schema文件不一致的原因是在从shema文件构造SDO对象时,遇到attribute,构造成的property的bisContainment属性没有重置为false,该属性的默认值为true。所以在从这个SDO对象生成schema文件时,property会被构造为element,而不是attribute。
在补丁程序中,只要在从attribute构造SDO对象的property时,将其bisContainment属性设为false即可。
下面是更正的方法,只在语句thisProperty.isElement = false;后添加了thisProperty.isContainment = false;语句:
void SDOSchemaSAX2Parser::startAttribute(
const SDOXMLString& localname,
const SDOXMLString& prefix,
const SDOXMLString& URI,
const SAX2Namespaces& namespaces,
const SAX2Attributes& attributes)
{
LOGINFO_1( INFO,"SchemaParser:startAttribute:%s",(const char*)localname);
if (!bInSchema) return;
PropertyDefinitionImpl thisProperty;
thisProperty.isElement = false;
thisProperty.isContainment = false; //!!!!!! new added. The default value of isContaintment is true. !!!!!!
setName(attributes,
thisProperty.name,
thisProperty.localname);
thisProperty.namespaceURI = schemaInfo.getTargetNamespaceURI();
setType(thisProperty, attributes, namespaces);
setCurrentProperty(thisProperty);
}
使用改正后的tuscany_sdo构造的shcema文件为:
//-------------generatedCompany2.xsd (使用改正后的 tuscany_sdo.dll) /* <xsd:schema xmlns:sdo="commonj.sdo" xmlns:sdoxml="commonj.sdo/xml" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="company" type="company"/> <xsd:complexType name="company"> <xsd:sequence> <xsd:element name="ename" type="xsd:String" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="aname" type="xsd:String"/> </xsd:complexType> </xsd:schema> */
这就与原来的company2.xsd文件保持一致了。