1
votes

I would like to know how to find a string in XML file.

Say this is the XML file i have (these are the SQL server instances btw, irrelevant)

<?xml version="1.0" encoding="utf-8" ?>
<Servernames>
    <loc country="Lockheed">
        <Servername>instance1\server1</Servername>
        <Servername>instance2\server2</Servername>
        <Servername>10.90</Servername>
    </loc>
    <loc country="SouthAmerica">
        <Servername>Hide your heart</Servername>
        <Servername>Bonnie Tyler</Servername>
        <Servername>10.0</Servername>
    </loc>
    <loc country="Britian">
        <Servername>Greatest\Hits</Servername>
        <Servername>Dolly\Parton</Servername>
        <Servername>this\is</Servername>
    </loc>
</Servernames>

So what happens is i get a string from the user in any format say for example i only get instance and then i want the listbox to display all the servernames that start with server in the above case it will be

instance1\server1
instance2\serve2

and so on.. Not sure how to achieve this, do i have to open stream reader or just get a string and browser thru the xml file?

UPDATED

private void button1_Click(object sender, RoutedEventArgs e)
{
    textBox1.Clear();
    string fileName = "c:\\users\\xxxx\\documents\\visual studio 2010\\Projects\\WpfApplication2\\WpfApplication2\\XML.xml";

        var doc = XDocument.Load(fileName);
        var findString = "Server";

        var results = doc.Element("Servernames").Descendants("Servername").Where(d => d.Value.Contains(findString)).Select(d => d.Value);
        listBox1.Items.Add(results.ToString());
        textBox1.Text = results.ToString();
}

i am simply getting this in the text box :System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String]

enter image description here

strong textUPDATE2

.cs file code

private void button1_Click(object sender, RoutedEventArgs e) { textBox1.Clear();

        string fileName = "c:\\users\\xxxxx\\documents\\visual studio 2010\\Projects\\WpfApplication2\\WpfApplication2\\XML.xml";

        var doc = XDocument.Load(fileName);
        var findString = "Server";

        var results = doc.Element("Servernames").Descendants("Servername").Where(d => d.Value.Contains(findString)).Select(d => d.Value);

        Servers = new ObservableCollection<string>(results);

        MessageBox.Show("THis is loaded");

    }

XAML looks like this

<ListBox   Height="200" HorizontalAlignment="Left" Margin="200,44,0,0" x:Name="ListBox1" VerticalAlignment="Top" Width="237">

enter image description here

2
You need to use an XDocument, not an XPathDocument. See updated answer below. - Robaticus
enumerate on results for ex., String.Join("\n",results) - L.B
nothing is being displayed if change the code to this. listBox1.Items.Add(String.Join("\n",results)); textBox1.Text = String.Join("\n", results); - JackyBoi
Hi @L.B how to use the enum in my code? - JackyBoi
The search is case sensitive. Make findString "server" instead of "Server". If you need a case insensitive search, then your "Where" becomes .Where (d => d.Value.ToLower().Contains(findString.ToLower())) - Robaticus

2 Answers

4
votes

You could do something like this, assuming you load the XML into an XDocument.

string fileName = "c:\\users\\xxxxx\\documents\\visual studio 2010\\Projects\\WpfApplication2\\WpfApplication2\\XML.xml";

var doc = XDocument.Load(fileName);
var findString = "server";

var results = doc.Element("Servernames").Descendants("Servername").Where (d => d.Value.Contains(findString)).Select (d => d.Value);

Edit - WPF Example

XAML:

<ListBox ItemSource="{Binding Servers}"/>

DataContext:

public ObservableCollection<string> Servers {get; set;}

string fileName = "c:\\users\\xxxxx\\documents\\visual studio 2010\\Projects\\WpfApplication2\\WpfApplication2\\XML.xml";

var doc = XDocument.Load(fileName);
var findString = "server";

var results = doc.Element("Servernames").Descendants("Servername").Where (d => d.Value.Contains(findString)).Select (d => d.Value);

Servers = new ObservableCollection<string>(results);

Edit2 - WPF Example without datacontext. You may want to read up on MVVM approach, as it is becoming the standard for WPF devleopment. Use this in the interim.

XAML:

<ListBox x:Name="ListBox1" />

DataContext:

string fileName = "c:\\users\\xxxxx\\documents\\visual studio 2010\\Projects\\WpfApplication2\\WpfApplication2\\XML.xml";

var doc = XDocument.Load(fileName);
var findString = "server";

var results = doc.Element("Servernames").Descendants("Servername").Where (d => d.Value.Contains(findString)).Select (d => d.Value);

foreach(string result in results)
{
     ListBox1.Items.Add(result);
}
1
votes

You can use XmlDocument like this:

string xml = "<your xml>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlNode xmlLoc in doc.DocumentElement.SelectNodes("loc"))
{
    foreach (XmlNode xmlServername in xmlLoc.SelectNodes("Servername"))
    {
        Debug.WriteLine(string.Format("Servername={0}", xmlServername.InnerText));
        // xmlServername.InnerText will be \instance1\server1, etc.
        // UPDATE: add item to listbox
        listBox1.Items.Add(xmlServername.InnerText);
    }
}