Fulltext Search On XML Files using XDocument
Given the following XML-Document:
<Customers>
<Customer>
 <Name>Jerry</Name>
 <Age>26</26>
 <Addresses>
<Address>
<Street>Main Street</Street>
<Address>
<Addresses>
<Customers>
1) How would you implement a fulltext search to return a List of Customer-Names?
public void StartRead(string searchTerm)
{
XDocument xDocument = XDocument.Parse(GetFile());
//get all retval-nodes (allthough it’s just 1)
var customers = from cmd in xDocument.Descendants(“Customer”)
select cmd;
//loop through retval-nodes (still only 1)
foreach (XElement cust in customers)
{
if (RecursiveParser(cust, searchTerm))
{
this.textBox1.Text += cust.Element(“Name”).Value + @” ### “;
}
else
{
this.textBox1.Text += @”empty ### “;
}
}
}
public bool RecursiveParser(XElement element, string searchTerm)
{
if (element.IsEmpty) return false;
if (element.HasElements)
{
foreach (XElement xElement in element.Elements())
{
if (xElement.Value.ToLower().Contains(searchTerm))
return true;
if (RecursiveParser(xElement, searchTerm))
return true;
}
}
return false;
}
2. How would you implement a fulltext search for addresses only?
Just replace “Customer” by “Address”:
//get all retval-nodes (allthough it’s just 1)
var customers = from cmd in xDocument.Descendants(“Address”)
select cmd;

Given the following XML-Document (it’s the output of a serialized List<Customer>):

<ArrayOfCustomer>
<Customer>
<Name>Jerry</Name>
<Age>26</Age>
<Addresses>
<Address>
<Street>Main Street</Street>
</Address>
</Addresses>
</Customer>
</ArrayOfCustomer>

1) How would you implement a fulltext search to return a List of Customer-Names?

public void StartRead(string searchTerm)
{
XDocument xDocument = XDocument.Parse(GetXmlFile()); 

//get all retval-nodes (allthough it’s just 1)
var customers = from cmd in xDocument.Descendants("Customer")
select cmd;

//loop through retval-nodes (still only 1)
foreach (XElement cust in customers)
{
if (RecursiveParser(cust, searchTerm))
{
Log(cust.Name);
}

}

public bool RecursiveParser(XElement element, string searchTerm)
{
if (element.IsEmpty) return false;
if (element.HasElements)
{
foreach (XElement xElement in element.Elements())
{
if (xElement.Value.ToLower().Contains(searchTerm))
return true;

if (RecursiveParser(xElement, searchTerm))
return true;
}
}

return false;
}

 

2. How would you implement a fulltext search for addresses only?

Hint: just replace “Customer” by “Address” in Function StartRead:

//get all retval-nodes (allthough it’s just 1)
var customers = from cmd in xDocument.Descendants("Address")

3. Want to see a much shorter version of the code from question 1?

//this version is originally from franz!
public void StartRead(string searchTerm)
{
XDocument xDocument = XDocument.Parse(GetXmlFile());

//replace "Customer" by "Loan", if you just want to scan Loans
var customers = xDocument.Descendants("Customer").Where(i => i.Value.ToLower().Contains(searchTerm)); //.Select(j => j.Value).ToList();

//loop through retval-nodes
foreach (XElement cust in customers)
{
Log(cust.Name);
}
}

Reason: The Property “Value” of an element contains ALL values from descendents also!
That’s why there is no need to recursivly parse the childnodes.