Solved

XML File Search Using VB.Net

Posted on 2013-06-03
6
502 Views
Last Modified: 2013-06-05
I want to create a search in VB.Net for all XML Filenames that meet the Search Criteria entered by a user. The User can enter information in any of four textboxes.

I have a form in VB.Net that has the four textboxes named:

Customer Number
Customer Name
Associate
City

So, for example, if the User enters:

1234 for the Customer Number
Podunk for the City
Allen as the Associate

The result is a list of XML filenames that meet this criteria. In the example with the data below, the result would be:

Podunk_1234_May232013.XML

The XML data below is in the file:  Podunk_1234_May232013.XML
<CustomerNotes>
  <CustomerNumber>1234</CustomerNumber>
  <Customer>Johnny Brokencode</Customer>
  <Associate>Allen Expert</Associate>
  <City>Podunk</City>
  <FileName>JohnnyBrokencode May232012.docx</FileName>
</CustomerNotes>

The XML contents of the following filename: Burgville_1234_April152013.XML
<CustomerNotes>
  <CustomerNumber>1234</CustomerNumber>
  <Customer>Johnny Brokencode</Customer>
  <Associate>Polly Procedure</Associate>
  <City>Burgville</City>
  <FileName>JohnnyBrokencode April152012.docx</FileName>
</CustomerNotes>

My search Function works for a single search term fine using the following function (some parts are redacted for this post - but it works).

Private Function FileSearch(ByVal Filename as String, ByRef ResultText As String) as Boolean  
        Dim xDoc As New XmlDocument
            xDoc.Load(Filename)
        Dim xNodes As XmlNodeList
            xNodes = xDoc.SelectNodes("CustomerNotes")
        Dim xNode As XmlNode
       Dim FindCustomerNumber As String

       Dim SearchString As String = ""
        Dim Result As Boolean = False
        ResultText = ""

        For Each xNode In xNodes
            SearchString = xNode.InnerText

            If SearchString.IndexOf(FindCaseNum) >= 0 Then
                Result = True
                ResultText = xNode.OuterXml
            End If
        Next

        If Result=False Then
            ResultText = "No Files Found"
        End If

        Return Result
End Function

My question is - what methods would you recommend to be able to search an XML file (Innertext) for multiple search criteria?  Having Nested loops seems just too messy (and possibly slow) with as many as 5 Search fields...

Thanks.
0
Comment
Question by:jrlittle86
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
6 Comments
 
LVL 42

Expert Comment

by:sedgwick
ID: 39218037
IF the xml file names contains the number and city, id first use regex to filter out xml files that doesnt meet those criterias.
That would save the time to parse xml files for no reason.
Secondly id use xpath to get the values of the search criterias cause the xml structure is the same for all files.
If u need code sample let me know and ill post one for you.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 39218271
here's a function which accept 3 criteria to look for the xml.
    Private Function GetFilesByCriteria(custNumber As String, city As String, associate As String) As List(Of String)
        Dim regFileName As Regex = New Regex(String.Format("^{0}_{1}_", city, custNumber))
        Dim files = Directory.GetFiles("c:\temp", "*.XML", SearchOption.AllDirectories).Where(Function(file) regFileName.IsMatch(Path.GetFileNameWithoutExtension(file)))
        Dim list As List(Of String) = New List(Of String)

        For Each file In files
            Dim root = XElement.Load(file)
            Dim assoc = root.Element("Associate").Value
            If (assoc = associate) Then
                list.Add(file)
            End If
        Next

        Return list

    End Function

Open in new window

the function logic has 2 phases:
1st phase is having regex to match file names using the custmNumber and city arguments.
so for example, for customNumber 1234 and city NewYork, the regex matches xml files which the file name is in the following pattern:
NewYork_1234_ .... .xml
i didn't handle nullable arguments and stuff like that.
2nd phase is the load result xml from previous regex match and look for the associate name also passed as argument to the function.
0
 

Author Comment

by:jrlittle86
ID: 39221086
Clever...and very observant!  Unfortunately - this wouldn't work in this case.

Here's why...

My XML filename example (with the city and customer number in the XML filename) was a happy coincidence. I probably should have listed them as some random file name.  The xml files can actually have any filename - and hence - that's why we must search on the contents.

A user really would search on any one of the fields or any combination of fields is this example...

ideas?
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 42

Expert Comment

by:sedgwick
ID: 39221163
ok, so regex is out of the window.
is it possible to have any combination of the 3 search criteria?
0
 
LVL 42

Accepted Solution

by:
sedgwick earned 500 total points
ID: 39221168
anyway, here's the updated function.
    Private Function GetFilesByCriteria(folder as string, custNumber As String, city As String, associate As String) As List(Of String)
        Dim files = Directory.GetFiles(folder, "*.XML", SearchOption.AllDirectories)
        Dim list As List(Of String) = New List(Of String)

        For Each file In files
            Dim root = XElement.Load(file)
            Dim assoc As Boolean = If(associate = Nothing, True, root.Element("Associate").Value = associate)
            Dim cityValue As Boolean = If(city = Nothing, True, root.Element("City").Value = city)
            Dim customerNumber As Boolean = If(custNumber = Nothing, True, root.Element("CustomerNumber").Value = custNumber)
            If (assoc And cityValue And customerNumber) Then
                list.Add(file)
            End If
        Next

        Return list

    End Function

Open in new window

in case user doesn't enter one of the search criteria, pass nothing as parameter.
so for instance, to get all xml files which match city = "NewYork" and customer number = 1234 but no associate then use:
dim result as List(Of String) = GetFilesByCriteria("c:\the-root-directory", "1234", "NewYork", nothing)

Open in new window

0
 

Author Comment

by:jrlittle86
ID: 39223148
Awesome. Brilliant. I think I like Linq. Many thanks!!!
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question