下面是测试用例:
//从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文件保持一致了。