Search code examples
c#xmlxsdxmlwriter

missing XML child element?


I am practicing for a school exam and I am not sure if I am doing this correctly. the exam is creating a xml file using a given schema. Am I missing a child element or am I just doing everything wrong. thanks

C#

   writer.WriteStartDocument();

            writer.WriteStartElement("LoanID");
            writer.WriteString("9980001140");

            writer.WriteStartElement("LoanAmount");
            writer.WriteString("150000");

            writer.WriteStartElement("BORROWER");
            writer.WriteString("John Smith");

            writer.WriteStartElement("FullName");
            writer.WriteString("Johnny Smoth");
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Close();

Schema

  <xs:complexType name="LOANDATA">
    <xs:sequence>
      <xs:element name="LoanID" nillable="false" type="xs:string"></xs:element>
      <xs:element name="LoanAmount" nillable="false" type="xs:double"></xs:element>
      <xs:element name="BORROWERS" maxOccurs="1" nillable="false" type="BORROWERS">      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="BORROWERS">
    <xs:sequence>
      <xs:element name="BORROWER" minOccurs="1" nillable="false" type="BORROWER"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="BORROWER">
    <xs:sequence>
      <xs:element name="FullName" nillable="false" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>

OUTPUT

<LoanID>
  9980001140
 <LoanAmount>
   150000
 <BORROWER>
  John Smith
 <FullName>Johnny Smoth</FullName>
 </BORROWER>
 </LoanAmount>
  </LoanID>

Solution

  • For starters your "schema" isn't actually a valid schema, it is just a fragment from one that defines some complex types.

    A full schema would look more like the below, where you are declaring it as a schema and defining the namespaces used.

    <?xml version="1.0" encoding="utf-16"?>
    <xs:schema xmlns="http://SomeNameSpace.LoanData" targetNamespace="http://SomeNameSpace.LoanData" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="LoanData">
        <xs:complexType>
          <xs:complexContent mixed="false">
            <xs:extension base="LOANDATA" />
          </xs:complexContent>
        </xs:complexType>
      </xs:element>
      <xs:complexType name="LOANDATA">
        <xs:sequence>
          <xs:element name="LoanID" nillable="false" type="xs:string" />
          <xs:element name="LoanAmount" nillable="false" type="xs:double" />
          <xs:element name="BORROWERS" maxOccurs="1" nillable="false" type="BORROWERS" />
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="BORROWERS">
        <xs:sequence>
          <xs:element name="BORROWER" minOccurs="1" nillable="false" type="BORROWER" />
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="BORROWER">
        <xs:sequence>
          <xs:element name="FullName" nillable="false" type="xs:string" />
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
    

    Secondly it would be better to code this using xmlserializer

    Use xsd.exe to create a class (e.g. xsd.exe /c loandata.xsd) and then having your class create an instance suitable populated.

    using System.IO;
    using System.Xml.Serialization;
    ...
    ...
            LoanData loan = new LoanData();
            loan.LoanID = "9980001140";
            loan.LoanAmount = 150000;
    
            BORROWER borrower = new BORROWER();
            borrower.FullName = "Johnny Smoth";
    
            loan.BORROWERS = new BORROWERS();
            loan.BORROWERS.BORROWER = new BORROWER();
    
            loan.BORROWERS.BORROWER = borrower;
    
            TextWriter writer = new StreamWriter("C:\\Test\\LoanData.xml");
    
            XmlSerializer ser = new XmlSerializer(typeof(LoanData));
            ser.Serialize(writer, loan);
            writer.Close();
    

    Output

    <?xml version="1.0" encoding="utf-8"?>
    <LoanData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://SomeNameSpace.LoanData">
      <LoanID xmlns="">9980001140</LoanID>
      <LoanAmount xmlns="">150000</LoanAmount>
      <BORROWERS xmlns="">
        <BORROWER>
          <FullName>Johnny Smoth</FullName>
        </BORROWER>
      </BORROWERS>
    </LoanData>
    

    If you do want to use XMLWriter then it should be

            writer.WriteStartDocument();
    
            writer.WriteStartElement("LoanData"); // Have a root node
    
            writer.WriteStartElement("LoanID");
            writer.WriteString("9980001140");
            writer.WriteEndElement();
    
            writer.WriteStartElement("LoanAmount");
            writer.WriteString("150000");
            writer.WriteEndElement();
    
            writer.WriteStartElement("BORROWERS");
            writer.WriteStartElement("BORROWER");
    
            writer.WriteStartElement("FullName");
            writer.WriteString("Johnny Smoth");
            writer.WriteEndElement(); // FullName
    
            writer.WriteEndElement(); // BORROWER
            writer.WriteEndElement(); // BORROWERS
            writer.WriteEndElement(); // LoanData
    
            writer.WriteEndDocument();
            writer.Close();
    

    Which has output of

    <?xml version="1.0" encoding="utf-8"?>
    <LoanData>
      <LoanID>9980001140</LoanID>
      <LoanAmount>150000</LoanAmount>
      <BORROWERS>
        <BORROWER>
          <FullName>Johnny Smoth</FullName>
        </BORROWER>
      </BORROWERS>
    </LoanData>