0

I have xml file. This is just piece of that file

1    <mainTerm>
2      <title> Abandonment </title>
3      <see> Maltreatment </see>
4    </mainTerm>
5    <mainTerm>
6      <title> Abasia <nemod>(-astasia) (hysterical) </nemod></title>
7      <code>F44.4</code>
8    </mainTerm>

I have a lot of <mainTerm> and i loop through all of them. I copy all data of elements, but when i reach line 6, i got the problem. How to copy all that content? I need get at the end string, that will looks like "Abasia (-astasia) (hysterical)".

That's the piece of my app that work with that file

     List<string> nodes = new List<string>();

            //Create XmlReaderSettings object
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            settings.IgnoreComments = true;

            //Create XmlReader object
            XmlReader xmlIn = XmlReader.Create(path, settings);

            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;
            object misValue = System.Reflection.Missing.Value;

            xlApp = new Excel.Application();
            xlWorkBook = xlApp.Workbooks.Add(misValue);
if (xmlIn.ReadToDescendant("mainTerm"))
{
 do
 {
   xmlIn.ReadStartElement("mainTerm");                                                  

   nodes.Add(xmlIn.ReadElementContentAsString());                          

   nodes.Add(xmlIn.ReadElementContentAsString());                          

 } while (xmlIn.ReadToNextSibling("mainTerm"));
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Bryuk
  • 3,295
  • 10
  • 45
  • 74
  • Be careful of the use of "text node". A text node is a specific type of XML Node that can only contain character data. I think you mean that mainTerm has "mixed content", i.e. character data and elements. – peter.murray.rust May 20 '13 at 17:55
  • update the question with your code – Damith May 20 '13 at 17:58
  • Yes, i mean "mixed content", but how i can get all data from mixed content to get result "Abasia (-astasia) (hysterical)"." – Bryuk May 20 '13 at 18:25

3 Answers3

1

You could use LINQ2XML. Just wrap your xml structure within a root node and fetch all title elements like this:

var xmlSrc = @"<?xml version=""1.0"" encoding=""UTF-8""?><xml><mainTerm>
  <title> Abandonment </title>
  <see> Maltreatment </see>
</mainTerm>
<mainTerm>
  <title> Abasia <nemod>(-astasia) (hysterical) </nemod></title>
  <code>F44.4</code>
</mainTerm></xml>";

var xml = XDocument.Parse(xmlSrc);
var mainTerms = xml.Root.Elements("mainTerm").ToList();
var titles = mainTerms.Elements("title").ToList();
foreach (var title in titles)
{
    System.Console.WriteLine(title.Value);
}

The output is:

Abandonment 
Abasia (-astasia) (hysterical) 

This is IMHO much easier than XPath and XmlReader.


Using the Descendants function your mainTerm element does not need to be the root element:

var mainTerms = xml.Root.Descendants("mainTerm").ToList();

This line delivers all mainTerm's at any level from the XML document!

keenthinker
  • 7,645
  • 2
  • 35
  • 45
  • Yes, maybe it's easy, but i have xml file with thousands of nodes and is not even root element. My xmlReader works ok, except element like in my example... All what i need its fix that – Bryuk May 20 '13 at 22:10
  • I have extended my answer with a code example that retrieves all mainTerm's regardless of element position in XML. – keenthinker May 21 '13 at 08:18
0

Read about xpath.

xpath check if node has text

xpath get node text

XmlReader xpath

Adam Tal
  • 5,911
  • 4
  • 29
  • 49
0

You need to use XmlDocument. I find using that is much easier than xmlreader. using your example...

1    <mainTerm>
2      <title> Abandonment </title>
3      <see> Maltreatment </see>
4    </mainTerm>
5    <mainTerm>
6      <title> Abasia <nemod>(-astasia) (hysterical) </nemod></title>
7      <code>F44.4</code>
8    </mainTerm>

Do something like this (Sorry, didn't have time to run this through a compiler... But this is the general idea)

XmlDocument example = new XmlDocument();

example.Load(StringWhereYouHaveYourXML); //You can also load Xml in other ways... check documentation

XmlNodeList mainTerm = example.SelectNodes("/mainTerm/"); //Now you have your list of Mainterms...
//Check for children in your nodes now...
forEach(XmlNode a in mainTerm){
   //check in the Title node for children that is
   XmlNode title = a.SelectSingleNode("/Title/");
   if (title.HasChildNodes){
      XmlNode abasia = title.SelectSingleNode("/nemod/");
   }
}

from there you can do what you want with the node. But you now have it defined more concretely.

SoftwareSavant
  • 9,467
  • 27
  • 121
  • 195