Question

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>
Was it helpful?

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>

OTHER TIPS

You've called XmlWriter.StartElement(string) 4 times, but XmlWriter.EndElement() only once.

You need to have a matching XmlWriter.WriteEnd*() call for every XmlWriter.WriteStart*() call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top