XML and Direct Pathing to a node

M

Mark Cooney

Good afternoon, yes i am a newby so pls keep it simple.

Yesterday I started a small project where I have to make an API call and
receive back from that the long xml transcript down below.

Now, not knowing about XML I have experienced one or 2 issues.

Firstly, this is the code I have created to make the call and then extract a
few bits of information:

'Create the web request

Dim request As HttpWebRequest =
WebRequest.Create(https://api.games.betfair.com/rest/v1/channels/1444074/snapshot?username=******)
request.Method = "GET"
request.Timeout = 5000

'Add headers to the web request
request.Headers.Add("gamexAPIAgent", ********@hotmail.co.uk.myGames.4.0)
request.Headers.Add("gamexAPIAgentInstance",
"0d69ee8290ee2f9b336c1f060e3497a5")
request.Headers.Add("gamexAPIPassword", "*******")

'Get response
Dim response As HttpWebResponse = request.GetResponse()

Dim reader As StreamReader = New StreamReader(response.GetResponseStream)
Dim objDoc As XmlReader = XmlReader.Create(reader)
objDoc.MoveToContent()
objDoc.ReadToFollowing("status")
Me.StatusTextBox.Text = objDoc.ReadElementContentAsString
objDoc.ReadToFollowing("game")
Me.GameIDTextBox.Text = objDoc.GetAttribute("id").ToString
objDoc.ReadToFollowing("round")
Me.RoundNumberTextBox.Text = objDoc.ReadElementContentAsString
objDoc.ReadToFollowing("bettingWindowPercentageComplete")
Me.PercentageTimeTextBox.Text = objDoc.ReadElementContentAsString
CallLabel.Text = "captured"
Catch ex As Exception
CallLabel.Text = "not captured"
End Try

For the most part this works fine but what I would rather do, is point
directly to the nodes listed in the code directly, now I have some tell me
"//channelSnaphot/channel/status" is the way to go through a
XMLSelectSingleNode, but I have tried and failed using that method.

Is there anyone out the who can improve on my code so I can make 20 or 30
direct calls to the nodes in the Stream Response I receive below? I am
pleased to say the layout of the response will never change so thats not an
issue i need to address.

Regards

API Call Returns the following:
<channelSnapshot>
<channel gameType="POKER" id="1444074" name="Exchange Poker Texas
Hold'em">
<status>RUNNING</status>
<game id="1817283">
<round>3</round>
<bettingWindowTime>45</bettingWindowTime>
<bettingWindowPercentageComplete>24</bettingWindowPercentageComplete>
<gameData>
<object name="Hand 1">
<description>One Pair, Fours, Ace High,
with Q, 8 Kickers</description>
<status>IN_PLAY</status>
<property name="Card 1" value="20"/>
<property name="Card 2" value="29"/>
</object>
<object name="Hand 2">
<description>One Pair, Sixes, Ace
High</description>
<status>IN_PLAY</status>
<property name="Card 1" value="5"/>
<property name="Card 2" value="44"/>
</object>
<object name="Hand 3">
<description>One Pair, Fours, Ace High,
with Q, 6 Kickers</description>
<status>IN_PLAY</status>
<property name="Card 1" value="31"/>
<property name="Card 2" value="42"/>
</object>
<object name="Hand 4">
<description>Ace High</description>
<status>IN_PLAY</status>
<property name="Card 1" value="49"/>
<property name="Card 2" value="45"/>
</object>
<object name="Community Cards">
<description/>
<status>N/A</status>
<property name="Card 1" value="3"/>
<property name="Card 2" value="13"/>
<property name="Card 3" value="11"/>
<property name="Card 4" value="NOT
AVAILABLE"/>
<property name="Card 5" value="NOT
AVAILABLE"/>
</object>
</gameData>
<markets currency="GBP">
<market id="5615051">
<status>ACTIVE</status>
<commissionRate>2.5</commissionRate>
<marketType>WIN_ONLY</marketType>
<selections type="MainBets">
<selection id="658439">
<name>Hand 1</name>
<resource
href="https://api.games.betfair.com/rest/v1/selection/tradeActivity?marketId=5615051&selectionId=658439"
responseType="selectionTradeActivity" title="Trade Activity"/>
<status>IN_PLAY</status>
<amountMatched>22.74</amountMatched>
<bestAvailableToBackPrices>
<price
amountUnmatched="204.42">6.6</price>
<price
amountUnmatched="381.64">6.55</price>
<price
amountUnmatched="576.92">6.5</price>
</bestAvailableToBackPrices>
<bestAvailableToLayPrices>
<price
amountUnmatched="74.6">6.7</price>
<price
amountUnmatched="504.74">6.75</price>
<price
amountUnmatched="551.44">6.8</price>
</bestAvailableToLayPrices>
</selection>
<selection id="658440">
<name>Hand 2</name>
<resource
href="https://api.games.betfair.com/rest/v1/selection/tradeActivity?marketId=5615051&selectionId=658440"
responseType="selectionTradeActivity" title="Trade Activity"/>
<status>IN_PLAY</status>
<amountMatched>88.68</amountMatched>
<bestAvailableToBackPrices>
<price
amountUnmatched="306.66">1.72</price>
<price
amountUnmatched="4127.36">1.71</price>
<price
amountUnmatched="59.63">1.7</price>
</bestAvailableToBackPrices>
<bestAvailableToLayPrices>
<price
amountUnmatched="99.98">1.73</price>
<price
amountUnmatched="2188.96">1.74</price>
<price
amountUnmatched="2200.77">1.75</price>
</bestAvailableToLayPrices>
</selection>
<selection id="658441">
<name>Hand 3</name>
<resource
href="https://api.games.betfair.com/rest/v1/selection/tradeActivity?marketId=5615051&selectionId=658441"
responseType="selectionTradeActivity" title="Trade Activity"/>
<status>IN_PLAY</status>
<amountMatched>102.9</amountMatched>
<bestAvailableToBackPrices>
<price
amountUnmatched="17.99">45.0</price>
<price
amountUnmatched="140.4">44.5</price>
<price
amountUnmatched="2.19">44.0</price>
</bestAvailableToBackPrices>
<bestAvailableToLayPrices>
<price
amountUnmatched="33.52">46.0</price>
<price
amountUnmatched="53.76">46.5</price>
<price
amountUnmatched="79.76">47.0</price>
</bestAvailableToLayPrices>
</selection>
<selection id="658442">
<name>Hand 4</name>
<resource
href="https://api.games.betfair.com/rest/v1/selection/tradeActivity?marketId=5615051&selectionId=658442"
responseType="selectionTradeActivity" title="Trade Activity"/>
<status>IN_PLAY</status>
<amountMatched>1020.0</amountMatched>
<bestAvailableToBackPrices>
<price
amountUnmatched="158.07">4.0</price>
<price
amountUnmatched="198.19">3.98</price>
<price
amountUnmatched="631.28">3.96</price>
</bestAvailableToBackPrices>
<bestAvailableToLayPrices>
<price
amountUnmatched="103.84">4.06</price>
<price
amountUnmatched="612.72">4.08</price>
<price
amountUnmatched="914.6">4.1</price>
</bestAvailableToLayPrices>
</selection>
</selections>
</market>
</markets>
</game>
</channel>
</channelSnapshot>
 
S

Stephany Young

Again with the changing of it!!!!!!!

I DID NOT say:

objDoc.SelectSingleNode("//channelSnaphot/channel/status")

I DID say:

objDoc.SelectSingleNode("//channel/status")

I don't know why you persist in inserting channelSnaphot/ into the query!

//channel/status means find me the first element called status that is a
descendant of an element called channel that occurs anywhere in the
document.
 
S

Stephany Young

Given the XML that you have provided, the following produces the results as
shown (I saved the XML to a file for the purpose of the exercise):

Dim _doc As New XmlDocument
_doc.Load("channelSnapshot.xml")
Dim _node As XmlNode = _doc.SelectSingleNode("//channel/status")
Console.WriteLine(_node.InnerText)
_node = _doc.SelectSingleNode("//channel/game")
Console.WriteLine(_node.Attributes("id").Value)
_node = _doc.SelectSingleNode("//channel/game/round")
Console.WriteLine(_node.InnerText)
_node =
_doc.SelectSingleNode("//channel/game/bettingWindowPercentageComplete")
Console.WriteLine(_node.InnerText)

Results
-------
RUNNING
1817283
3
24

If you change the XPath expressions or change the scope of the
SelectSingleNode method, then it will not work.

Out of interest, what do you get if you execute the equivalent of:

Console.WriteLine(_doc.OuterXml)

immediately after 'loading' the XmlDocument object from the StreamReader
object?
 
M

Mark Cooney

I get the following, sorry no formatting, when i put your code into my
program it still does not work so what am i missing?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="/rest/apiStylesheet.xsl" ?>
<channelSnapshot xmlns="urn:betfair:games:api:v1">
<channel gameType="POKER" id="1444074" name="Exchange Poker Texas
Hold'em">
<status>RUNNING</status>
<game id="1823743">
<round>2</round>
<bettingWindowTime>60</bettingWindowTime>
<bettingWindowPercentageComplete>25</bettingWindowPercentageComplete>
<gameData>
<object name="Hand 1">
<description /><status>IN_PLAY</status><property name="Card 1"
value="26" /><property name="Card 2" value="1" /></object><object name="Hand
2"><description /><status>IN_PLAY</status><property name="Card 1" value="22"
/><property name="Card 2" value="34" /></object><object name="Hand
3"><description /><status>IN_PLAY</status><property name="Card 1" value="7"
/><property name="Card 2" value="47" /></object><object name="Hand
4"><description /><status>IN_PLAY</status><property name="Card 1" value="39"
/><property name="Card 2" value="33" /></object><object name="Community
Cards"><description /><status>N/A</status><property name="Card 1" value="NOT
AVAILABLE" /><property name="Card 2" value="NOT AVAILABLE" /><property
name="Card 3" value="NOT AVAILABLE" /><property name="Card 4" value="NOT
AVAILABLE" /><property name="Card 5" value="NOT AVAILABLE"
/></object></gameData><markets currency="GBP"><market
id="5627743"><status>ACTIVE</status><commissionRate>2.5</commissionRate><marketType>WIN_ONLY</marketType><selections
type="MainBets"><selection id="658439"><name>Hand 1</name><resource
href="https://api.games.betfair.com/rest/...s&amp;marketId=5627743&amp;selectionId=658439"
responseType="selectionTradeActivity" title="Trade Activity"
/><status>IN_PLAY</status><amountMatched>148.76</amountMatched><bestAvailableToBackPrices><price
amountUnmatched="146.29">4.3</price><price
amountUnmatched="785.42">4.28</price><price
amountUnmatched="880.28">4.26</price></bestAvailableToBackPrices><bestAvailableToLayPrices><price
amountUnmatched="62.16">4.34</price><price
amountUnmatched="228.21">4.36</price><price
amountUnmatched="570.76">4.38</price></bestAvailableToLayPrices></selection><selection
id="658440"><name>Hand 2</name><resource
href="https://api.games.betfair.com/rest/...s&amp;marketId=5627743&amp;selectionId=658440"
responseType="selectionTradeActivity" title="Trade Activity"
/><status>IN_PLAY</status><amountMatched>79.38</amountMatched><bestAvailableToBackPrices><price
amountUnmatched="263.15">2.94</price><price
amountUnmatched="1109.2">2.93</price><price
amountUnmatched="1288.64">2.91</price></bestAvailableToBackPrices><bestAvailableToLayPrices><price
amountUnmatched="183.92">2.97</price><price
amountUnmatched="294.17">2.98</price><price
amountUnmatched="836.12">2.99</price></bestAvailableToLayPrices></selection><selection
id="658441"><name>Hand 3</name><resource
href="https://api.games.betfair.com/rest/...s&amp;marketId=5627743&amp;selectionId=658441"
responseType="selectionTradeActivity" title="Trade Activity"
/><status>IN_PLAY</status><amountMatched>173.92</amountMatched><bestAvailableToBackPrices><price
amountUnmatched="50.6">7.8</price><price
amountUnmatched="447.26">7.75</price><price
amountUnmatched="487.0">7.7</price></bestAvailableToBackPrices><bestAvailableToLayPrices><price
amountUnmatched="169.6">7.9</price><price
amountUnmatched="314.44">7.95</price><price
amountUnmatched="468.72">8.0</price></bestAvailableToLayPrices></selection><selection
id="658442"><name>Hand 4</name><resource
href="https://api.games.betfair.com/rest/...s&amp;marketId=5627743&amp;selectionId=658442"
responseType="selectionTradeActivity" title="Trade Activity"
/><status>IN_PLAY</status><amountMatched>131.4</amountMatched><bestAvailableToBackPrices><price
amountUnmatched="381.11">3.28</price><price
amountUnmatched="766.84">3.26</price><price
amountUnmatched="1157.4">3.24</price></bestAvailableToBackPrices><bestAvailableToLayPrices><price
amountUnmatched="230.47">3.32</price><price
amountUnmatched="973.0">3.34</price><price
amountUnmatched="1116.04">3.36</price></bestAvailableToLayPrices></selection></selections></market></markets></game></channel></channelSnapshot>
 
S

Stephany Young

OK ...

What results do you get as you interrogate each node?

If you get exceptions then please post the full exception information.
 
S

Stephany Young

The full exception information please.

And at what statement does the exception occur?
 
M

Mark Cooney

Dim _doc As New XmlDocument

_doc.Load(reader)

TextBox1.Text = (_doc.OuterXml)

Dim _node As XmlNode = _doc.SelectSingleNode("//channel/status")

StatusTextBox.Text = _node.InnerText 'This is where it breaks and it says

NullReferenceException was unhandled
Object reference not set to an instance of an object
 
S

Stephany Young

Humour me ...

What results do you get if you add the statement:

reader.Close()

directly after the statement:

_doc.Load(reader)
 
M

Mark Cooney

OK

It works if I work the api direct from a file and that only if I copy
straight from the api in internet browser but not from the stream.
 
M

Mark Cooney

reader.Close()

Same result


Stephany Young said:
Humour me ...

What results do you get if you add the statement:

reader.Close()

directly after the statement:

_doc.Load(reader)
 
S

Stephany Young

OK ... A couple of things to try:

Instead of:

_doc.Load(reader)

try:

_doc.LoadXml(reader.ReadToEnd())

If that still fails try:

Dim reader As StreamReader = New StreamReader(response.GetResponseStream,
Encoding.UTF8)

Let us know how you get on.
 
M

Mark Cooney

Same results

Is it because from the stream you get these two extra lines at the beginning
of the stream?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?xml-stylesheet
type="text/xsl" href="/rest/apiStylesheet.xsl" ?>

The help you are giving me is very much appriciated
 
S

Stephany Young

No. They are ProcessingInstruction elements as oppossed to node elements.

I am expecting that XPath should be ignoring them but I usually deal with
xml streams that only have one ProcessingInstruction, (the <?xml
version="1.0" encoding="UTF-8" standalone="yes"?> one), so let's just take
them out of play.

Vary the statement to find the nodes so that instead of operating from the
XmlDocument object, they operate explicitly from the root element
(channelSnapshot). This should work because channel is a child of
channelSnapshot.

Dim _node As XmlNode =
_doc.DocumentElement.SelectSingleNode("channel/status")

_node = _doc.DocumentElement.SelectSingleNode("channel/game")

_node =
_doc.DocumentElement.SelectSingleNode("channel/bettingWindowPercentageComplete")

Note the difference, _doc.DocumentElement.SelectSingleNode instead of
_doc.SelectSingleNode.

_doc.DocumentElement is reference to the root element (channelSnapshot).

Not also that there is NO / before channel in the XPath expression.

Another point, in case you are typing this stuff yourself, is that XML is
case-sensitive. <channel> and <Channel> are not the same element.
 
M

Mark Cooney

Stephany

Thanks for you help

I did work something out, I put the information in a dataset and used GetXml
and it just extracted the xml and not the processing-information().

Thanks again
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top