Issue while converting XSD with complextype to XML using MSDN Microsoft.Xml.XMLGen( XmlSampleGenerator API)

耗尽温柔 提交于 2019-12-23 06:10:52

问题


I am trying to convert an XSD with complex type into XML I could not getting the expected result. The xsd is shown below.

But only one of the node showing correct data but the second one not showing the correct result attaching the screenshot enter image description here any idea on this?? I can able to convert it through online, at that time it is working fine Do we have any limitation in samplegenerator to use same complex type in multiplenode?

Here is the XSD:

<xs:schema xmlns:xs="w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="XXX">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Applicant">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="PrimaryEmployment" type="EmploymentType"/>
                        <xs:element name="SecondEmployment" type="EmploymentType"/>
                    </xs:sequence>
                    <xs:attribute name="type" type="xs:string"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:complexType name="EmploymentType">
    <xs:sequence>
        <xs:element name="TimeAtEmployer">
            <xs:complexType>
                <xs:sequence> 
                    <xs:element name="Years" type="xs:int"/>
                    <xs:element name="Months" type="xs:int" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:sequence>
</xs:complexType>

Expected xml file

<Applicant>
<PrimaryEmployment>
  <TimeAtEmployer>
    <Years>123</Years>
    <Months>123</Months>
  </TimeAtEmployer>
</PrimaryEmployment>
<SecondEmployment>
  <TimeAtEmployer>
    <Years>123</Years>
    <Months>123</Months>
  </TimeAtEmployer>
</SecondEmployment>

Current XML

`<Applicant>
        <PrimaryEmployment>
          <TimeAtEmployer>
            <Years>123</Years>
            <Months>123</Months>
          </TimeAtEmployer>
        </PrimaryEmployment>
        <SecondEmployment>
          <TimeAtEmployer>      
          </TimeAtEmployer>
        </SecondEmployment>
      </Applicant>`

Sample code that i have tried

XmlTextWriter textWriter = new XmlTextWriter("po.xml", null);
        textWriter.Formatting = Formatting.Indented;
        XmlQualifiedName qname = new XmlQualifiedName("Loancontract", "http://tempuri.org");
        XmlSampleGenerator generator = new XmlSampleGenerator("sample.xsd", qname);
        generator.WriteXml(textWriter);

Example2

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xml;
            var rootElement = new XmlQualifiedName("sampledata");
            var XSD = @"<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" elementFormDefault=""qualified"" attributeFormDefault=""unqualified""> 
                <xs:element name = ""SampleData2"">

                <xs:complexType>

                <xs:sequence>

                <xs:element name = ""Applicant"">

                <xs:complexType>

                <xs:sequence>

                <xs:element name = ""PrimaryEmployment"" type = ""EmploymentType""/>

                <xs:element name = ""SecondEmployment"" type = ""EmploymentType""/>

                </xs:sequence>

                </xs:complexType>

                </xs:element>

                </xs:sequence>

                </xs:complexType>

                </xs:element>

                <xs:complexType name = ""EmploymentType"">

                <xs:sequence>

                <xs:element name = ""TimeAtEmployer"">

                <xs:complexType>

                <xs:sequence>

                <xs:element name = ""Years"" type = ""xs:int""/>

                <xs:element name = ""Months"" type = ""xs:int""/>

                </xs:sequence>

                </xs:complexType>

                </xs:element>

                </xs:sequence>
                </xs:complexType>
                </xs:schema>
                ";
            XmlElement serializedElement = Serialize(XSD);
        }
        public static XmlDocument GetXml(string xsd, XmlQualifiedName rootElem)
        {
            var reader = XmlReader.Create(new StringReader(xsd), new XmlReaderSettings
            {
                DtdProcessing = DtdProcessing.Prohibit
            });

            XmlSchema schema = XmlSchema.Read(reader, null);
            var generator = new XmlSampleGenerator(schema, rootElem);
            generator.MaxThreshold = 2;

            var xmlStringBuilder = new StringBuilder();
            var writer = XmlWriter.Create(xmlStringBuilder);
            generator.WriteXml(writer);

            var resultXmlDoc = new XmlDocument();
            resultXmlDoc.LoadXml(xmlStringBuilder.ToString());
            //BlankOutValues(resultXmlDoc.DocumentElement);
            return resultXmlDoc;
        }
        public static XmlElement Serialize(object transformObject)
        {
            XmlElement serializedElement = null;

            MemoryStream memStream = new MemoryStream();
            XmlSerializer serializer = new XmlSerializer(transformObject.GetType());
            serializer.Serialize(memStream, transformObject);
            memStream.Position = 0;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(memStream);
            var reader = XmlReader.Create(new StringReader(new StreamReader(memStream).ReadToEnd().Replace("utf-8", "utf-16")), new XmlReaderSettings
            {
                DtdProcessing = DtdProcessing.Prohibit
            });
            XmlDocument xsd = new XmlDocument();
            var rootElement = new XmlQualifiedName("LoanContract");
            xsd = GetXml(transformObject.ToString(), rootElement);
            return serializedElement;

        }
    }
}

回答1:


I think you need to change the XmlSampleGenerator.dll

private bool GenerateElement(XmlSchemaElement e, bool root, InstanceGroup parentElem, XmlSchemaAny any) {
         XmlSchemaElement eGlobalDecl = e;
         bool flagCached = false;
         if (!e.RefName.IsEmpty) {
               eGlobalDecl = (XmlSchemaElement)schemaSet.GlobalElements[e.QualifiedName];
         }
         if (!eGlobalDecl.IsAbstract) {
               InstanceElement elem = (InstanceElement)elementTypesProcessed[eGlobalDecl];
               if (elem != null) {
                   Debug.Assert(!root);
                   if (any == null && e.MinOccurs > 0) { //If not generating for any or optional ref to cyclic global element
                       decimal occurs = e.MaxOccurs;
                       if (e.MaxOccurs >= maxThreshold) {
                           occurs = maxThreshold;
                       }
                       if (e.MinOccurs > occurs) {
                           occurs = e.MinOccurs;
                       }
                       elem = elem.Clone(occurs);
                       parentElem.AddChild(elem);
                       flagCached = true;
                   }
               }
               else
               {
                   elem = new InstanceElement(eGlobalDecl.QualifiedName);
               }
               if(root) {
                   instanceRoot = elem;
               }
               else {
                   if(!flagCached)
                   parentElem.AddChild(elem);
                   flagCached = false;
               }
               //Get minOccurs, maxOccurs alone from the current particle, everything else pick up from globalDecl
               if (any != null) { //Element from any
                   elem.Occurs = any.MaxOccurs >= maxThreshold ? maxThreshold : any.MaxOccurs;
                   elem.Occurs = any.MinOccurs > elem.Occurs ? any.MinOccurs : elem.Occurs;
               }
               else {
                   elem.Occurs = e.MaxOccurs >= maxThreshold ? maxThreshold : e.MaxOccurs;
                   elem.Occurs = e.MinOccurs > elem.Occurs ? e.MinOccurs : elem.Occurs;
               }
               elem.DefaultValue = eGlobalDecl.DefaultValue;
               elem.FixedValue = eGlobalDecl.FixedValue;
               elem.IsNillable = eGlobalDecl.IsNillable;
               if (eGlobalDecl.ElementSchemaType == AnyType) {
                   elem.ValueGenerator = XmlValueGenerator.AnyGenerator;
               }
               else {
                   XmlSchemaComplexType ct = eGlobalDecl.ElementSchemaType as XmlSchemaComplexType;
                   if (ct != null) {
                       if(!elementTypesProcessed.ContainsKey(eGlobalDecl)) elementTypesProcessed.Add(eGlobalDecl, elem);
                       if (!ct.IsAbstract) {
                           elem.IsMixed = ct.IsMixed;
                           ProcessComplexType(ct, elem);
                       }
                       else { // Ct is abstract, need to generate instance elements with xsi:type
                           XmlSchemaComplexType dt = GetDerivedType(ct);
                           if (dt != null) {
                               elem.XsiType = dt.QualifiedName;
                               ProcessComplexType(dt, elem);
                           }
                       }
                   }
                   else { //elementType is XmlSchemaSimpleType
                       elem.ValueGenerator = XmlValueGenerator.CreateGenerator(eGlobalDecl.ElementSchemaType.Datatype, listLength);
                   }
               }
               if (elem.ValueGenerator != null && elem.ValueGenerator.Prefix == null) {
                   elem.ValueGenerator.Prefix = elem.QualifiedName.Name;
               }
               return true;
         } // End of e.IsAbstract
         return false;
       }

It is working for me,Please check



来源:https://stackoverflow.com/questions/58168306/issue-while-converting-xsd-with-complextype-to-xml-using-msdn-microsoft-xml-xmlg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!