Проблема при преобразовании XSD со сложным типом в XML с использованием MSDN Microsoft.Xml.XMLGen (API XmlSampleGenerator) - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь преобразовать XSD со сложным типом в XML, я не смог получить ожидаемый результат. Xsd показан ниже.

Но только один из узлов показывает правильные данные, а второй не показывает правильный результат, прикрепляя скриншот введите описание изображения здесь есть идеи по этому поводу ?? Я могу преобразовать его через Интернет, в то время как он работает нормально. Есть ли у нас какие-либо ограничения в сэмплегенераторе для использования одного и того же сложного типа во множественном узле?

Вот 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>

Ожидаемый XML-файл

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

Текущий XML

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

Пример кода, который я пробовал

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 Ответ

0 голосов
/ 03 октября 2019

Я думаю, вам нужно изменить 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;
       }

Это работает для меня, пожалуйста, проверьте

...