Something that has been on top of my list of improvements needed for XML in Visual Studio is better support for writing and testing XPath queries. Currently, the only way to write and test your XPath statements is to either create your own console or Window application, create a test XSLT (using the XSLT debugger), or worse, put break points in your code, and use the edit and continue feature. Well, I heard that Visual Studio extensibility has been greatly improved in Visual Studio 2005, so I figured that I would attempt to extend the XML Editor (yes Virginia there is an XML Editor in Visual Studio) to include support for XPath. The project is called XPathmania and is part of the open source Mvp.Xml project (www.mvpxml.org). The XML MVPs are in the middle of moving our code base to CodePlex, but since this is a new project under the Mvp.Xml umbrella, all of the code and releases are already hosted on CodePlex MvpXml page.
In this, the first version, I decided to keep things pretty simple by just creating a Visual Studio Tool Window where a developer can write an XPath statement and test it against the current document in the XML Editor. After running an XPath query it will list and highlight the nodes returned from the query. In a future version, I would like to see Intellisense, adding schema awareness, and even some code snippet generation. You can download XPathmania 1.0 Release Candidate 1.1 as an install package, and/or if you want to see how it is done, you can download the source code (you will need to install the Visual Studio SDK – April 2006 release if you want to compile it yourself). After you install XPathmania or compile it yourself you will have to tell Visual Studio to display the XPathmania tool window thru the View|Other Windows menu list and select XPathmania. XPathmania will then be a floating window at this point, but you can click on the title bar and then dock it. I prefer docking it to the bottom of Visual Studio, but you can place it just about anywhere that makes sense to you.
Image 1- Displaying the XPathmania Tool Window
Image 2 – Docking XPathmania
Now that we have the tool window displayed, let’s see what it can do. To run a query against an XML document, you are going to need a document. In this case, I’ll create a new document that contains the information that I wish to query, a listing of compact disks with the artist name and the title of the CD. I wish to find all CDs in this document for the artist Buckcherry, and the XPath statement is //music/cd[artist/name='Buckcherry']. If we enter the query into the XPath Text Box and hit enter (or click the Query button), the query will execute and the nodes that match the query will be highlighted in the XML Editor, plus they will be listed in the XPathmania Tool Window.
Image 3 – Executing a query
If you double click on a results row, it will automatically select that node in the XML Editor (and even scroll to that node if it isn’t currently in the viewable area). Plus, if you edit the XML document, the results in the tool window are kept in sync with the XML document. So if you move a node, or delete the node, the new information will be reflected in the Results grid. Note – any new nodes added to the XML document will not be reflected in the results. To see the results based on the latest version of the XML document, re-execute the query by clicking on the Query button.
But, we all know that XML without at least one namespace is not much better then delimited text files (aka naked XML), so we should add a namespace to this XML document. This way there is an identifier in the XML document that can help the consumer what type (schema or structure) the XML conforms to. We can do this a number of similar ways, but let’s pick the easiest, by adding the attribute xmlns=”urn:mvpxml.org/music” to the music element, and run the XPath query again. But this time, instead of getting the same results as before, we get an Error Tab with the message “Document has a default namespace. Did you make sure to add it to the Namespace Table and use its prefix in your XPath query?”.
Image 4 – Default Namespace Error
What gives? All we did is add a namespace to the document. Well, the reason is due to this little back corner of the XPath spec. You can read the details for yourself, but in the end, you need to add a way to map prefixes in your XPath query to namespaces (both in your query and in the XML document). This is one of the most common questions on the newsgroups, and hopefully folks will use this tool to learn to write XPath queries, correctly. We can do this by adding a little guidance to the error messages (and eventually intellisense).
So, let’s do like the error message suggests and add the namespace to the Namespace Table. Just click on the Namespace Table tab and enter the prefix “a” into the first column and the namespace “urn:mvpxml.org/music” to the second column (you can’t leave the prefix column empty, otherwise you will get another error message). Then add the prefix to each element in your XPath query, so it looks like this: //a:music/a:cd[a:artist/a:name='Buckcherry'] and then execute the query again. Great, now we got the results that we were looking for. But what if the XML document doesn’t use a default namespace and the namespace used the prefix “b” instead of nothing (the default)? Let’s go in and change the document to match this scenario and run the exact same XPath query using the prefix of “a”.
Image 5 – XML with Namespace and Prefix
Wow, the query still works! The XPath Data Model only uses the prefix as a sort of quick way to refer to the full namespace. This way the prefixes used within the XML document does not have to be the same ones used in the XPath query, which is good, since the system that generated the XML doesn’t have always use the same prefix (although you will normally find that they do use the same prefix, but they do not really have to).
For this version of XPathmania, that’s about all it can do, execute some XPath queries and give a little guidance on handling default namespaces. There are lots of other possible enhancements that I can think may be of some value, but I will rely on you to suggest other improvements and bug fixes. Please use the CodePlex MvpXml Discussion page to leave comments/suggestions/bug reports, and if you are interested in helping with the project, well, we would love the help.