Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML element with multiple different Text elements

Tags:

c#

xml

I have the following elements as part of an XML document:

<RegisterEntry>
    <EntryNumber>3</EntryNumber>
    <EntryDate>2009-01-30</EntryDate>
    <EntryType>Registered Charges</EntryType>
    <EntryText>REGISTERED CHARGE dated 30 December 2008.</EntryText>
</RegisterEntry>
<RegisterEntry>
    <EntryNumber>4</EntryNumber>
    <EntryType>Registered Charges</EntryType>
    <EntryText>REGISTERED CHARGE dated 30 December 2008.</EntryText>
</RegisterEntry>

I am using XmlReader to iterate through the document. The RegisterEntry is an XMLNodeType.Element and the four enclosed in this element are XmlNodeType.Text. How can I assign each of these Text values to a different variable as the XmlReader returns an empty string for Node.Name on a NodeType.Text. Also, the repeated elements do not always have the same number of text elements. Code below:

XmlTextReader reader = new XmlTextReader(fName);

if(reader.NodeType == XmlNodeType.Element && reader.Name =="RegisterEntry")
{
    propEntryNo = "";
    propEntryDate = "";
    propEntryType = "";
    propEntryText = "";

    while(reader.Read())
    {
        if(reader.NodeType == XmlNodeType.Text && reader.Name == "EntryNumber" && reader.HasValue)
        {
            propEntryNo = reader.Value;
        }

        if (reader.NodeType == XmlNodeType.Text && reader.Name == "EntryDate" && reader.HasValue)
        {
            propEntryDate = reader.Value;
        }

        if (reader.NodeType == XmlNodeType.Text && reader.Name == "EntryType" && reader.HasValue)
        {
            propEntryType = reader.Value;
        }

        if (reader.NodeType == XmlNodeType.Text && reader.Name == "EntryText" && reader.HasValue)
        {
            propEntryText += reader.Value + ",";
        }
        if(reader.NodeType == XmlNodeType.EndElement && reader.Name == "RegisterEntry")
        {
            add variable values to list
            break;
        }
    }
}

In each of the if statements above the NodeType returns as Text and the Name as an empty string.

like image 746
Allen Jones Avatar asked Sep 04 '26 15:09

Allen Jones


1 Answers

The XML element and the text inside are different nodes!

You have to read the content of the XML element first. Simple example:

switch (reader.Name)
{
    // found a node with name = "EntryNumber" (type = Element)
    case "EntryNumber":
        // make sure it's not the closing tag
        if (reader.IsStartElement())
        {
            // read the text inside the element, which is a seperate node (type = Text)
            reader.Read();
            // get the value of the text node
            propEntryNo = reader.Value;
        }
        break;
    // ...
}

Another option would be ReadElementContentAsString

switch (reader.Name)
{
    case "EntryNumber":
        propEntryNo = reader.ReadElementContentAsString();
        break;
    // ...
}

Of course, these simple examples assume that the XML is in the expected format. You should include appropriate checks in your code.

As for the other suggested solutions:

  • You could XmlDocument or XDocument or instead. The handling is easier, but the memory overhead is bigger (see also).

  • Deserializing the XML into objects is another option. But I feel handling errors caused by an unexpected format is trickier then.

like image 198
marsze Avatar answered Sep 07 '26 05:09

marsze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!