Introduction
I can't remember the whole grammars for XPath or JPath. When I need it as necessary, then I have been looking for the right path strings on the internet. So, I wanted to know that I'm writing the right path for getting a single value from my XML or JSON string
. So, I made a simple program for test like this.
Background
I know you already know the XML and JSON format though, if you do not, you should study it first. :) XML format is composed of nodes surrounded by angle brackets and values were in between each nodes. By comparison, JSON is composed of curly brackets which has a key and value. and the value can be defined by many types like integer, string, and array. To represent a array, it is presented by square brackets.
The following string
below is an example for XML. I got it from MSDN:
="1.0"="utf-8"
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
The following one is an example for Json. I got this from this site.
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
Using the Code
I will upload my project though, I made two multiline textbox
es which were having XML string
, JSON string
.
The first one named 'txtXmlSource
', the other is 'txtJsonSource
'.
Then, I need two textbox
es for inputting some path, 'txtXPath
' and 'txtJPath
'. Those are used for your searches.
Then, when each job of finding value is finished, there will appear two textbox
es, named 'txtXpathResult
' and 'txtJPathresult
'.
See this code below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.XPath;
using System.Windows.Forms;
using Newtonsoft;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace XmlJsonTest
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void FormMain_Load(object sender, EventArgs e)
{
}
private void btnXmlSearch_Click(object sender, EventArgs e)
{
try
{
using (StringReader readerPost = new StringReader(txtXmlSource.Text))
{
XPathDocument xDoc = new XPathDocument(readerPost);
XPathNavigator xNav = xDoc.CreateNavigator();
#region empty namespace set
XmlNamespaceManager ns = new XmlNamespaceManager(xNav.NameTable);
var nodes = xNav.Select("//*");
while (nodes.MoveNext())
{
var nsis = nodes.Current.GetNamespacesInScope(XmlNamespaceScope.Local);
foreach (var nsi in nsis)
{
var prf = (String.IsNullOrEmpty(nsi.Key)) ? "global" : nsi.Key;
if (String.IsNullOrEmpty(nsi.Value)) continue;
ns.AddNamespace(prf, nsi.Value);
}
}
#endregion
XPathExpression expression = xNav.Compile(txtXPath.Text);
expression.SetContext(ns);
XPathNavigator successNav = xNav.SelectSingleNode(expression);
if (successNav != null)
{
txtXPathResult.Text = successNav.Value;
}
else
{
txtXPathResult.Text = "";
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void btnJSonSearch_Click(object sender, EventArgs e)
{
try
{
JObject jo = JObject.Parse(txtJSonSource.Text);
IEnumerable<JToken> rst = jo.SelectTokens(txtJPath.Text);
if (rst.Count() > 0)
{
txtJPathResult.Text = rst.First().ToString();
}
else
txtJPathResult.Text = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
As you may have known, you need to install 'Newtonsoft' for JSon. Use a 'Package Manage Console' (at your Visual Studio's top menu -> tool -> nuget package manager). The command to install is like this:
PM> Install-Package Newtonsoft.Json
History