LINQ to XML , retrieving data - vb.net

I have this XML:
<root>
<data name="lnkViewResultResource1.Text" xml:space="preserve">
<value>bekijk de resultaten</value>
</data>
<data name="lnkVoteResource1.Text" xml:space="preserve">
<value>stem</value>
</data>
<data name="number of results" xml:space="preserve">
<value>er waren reeds {0} stemmen op deze poll {1}</value>
</data>
</root>
I want to retrieve the "data" values, and for this I used:
Public Shared Function getlabels(ByVal filename As String) As Array
Dim labels = From l In XElement.Load(filename).Descendants("root").Elements("data") Select l
Return labels.ToArray
But, unfortunately, it is not working, it is not getting anything.
Any ideas?
Thanks in advance.
Alf.

You're loading the <root> XElement and asking it for descendants called root. Just get rid of the Descendants("root") call and it should be okay.
On the other hand, the query expression is pretty pointless... just use:
Return XElement.Load(filename).Elements("data").ToArray

Try
Dim labels = From l In XElement.Load(filename).Descendants("data") Select l

Related

Verifying data from xpath location having multiple data

I have XML like below where I need to verify XML with lot of data with same names (index appended)
like below.
I don't want to give separate column for each name,mobile etc. So in Example I am passing sum,men,1212121212,682312;suj,men,2212121212,682312**;**suu,men,3212121212,682312 OR I can pass in JSON format
1. What is the best way to do this without using Java Code.
2. *def strVals=get response/Response/transaction/values
And print strVals
- Not printing any value
<Response>
<RequestID>1</RequestID>
<transaction>
<values>
<data name="firstName0">sum</data>
<data name="lastName0">men</data>
<data name="mobile0">1212121212</data>
<data name="zip0">682312</data>
<data name="firstName1">suj</data>
<data name="lastName1">men</data>
<data name="mobile1">2212121212</data>
<data name="zip1">682312</data>
<data name="firstName2">suu</data>
<data name="lastName2">men</data>
<data name="mobile2">3212121212</data>
<data name="zip2">682312</data>
<data name="firstName3">ssss</data>
<data name="lastName3">mmmmmmm</data>
<data name="mobile3">4212121212</data>
<data name="zip3">682312</data>
</values>
</transaction>
</Response>
I'll provide a hint on how to dynamically build this XML, the rest is up to you:
* def temp = <values></values>
* def data = [{first: 'John', value: 'foo'}, {first: 'Smith', value: 'bar'}]
* def fun =
"""
function(x, i){
var path = '/values/data[' + (i + 1) + ']';
karate.set('temp', path + '/#name', 'firstName' + i);
karate.set('temp', path, x.value);
}
"""
* karate.forEach(data, fun)
* print temp
Which will result in:
<values>
<data name="firstName0">foo</data>
<data name="firstName1">bar</data>
</values>

XPath doesn't provide proper tag

I'm trying to get tag "" from xml below.
If i execute request like this:
WITH x(col) AS (select'<document xmlns="http://example.com/digital/back/" xmlns:ns2="http://example.com/digital/back/complexId" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="">
<header>
<docId>13a2f29a28b12ecb</docId>
<dt>2018-12-10T11:59:48.112+03:00</dt>
</header>
<pay>
<reqTransfer id="154638">
<source>
<card>
<virtualCardNum>4B74C1EE187</virtualCardNum>
<bsc>VISA</bsc>
</card>
</source>
</reqTransfer>
</pay>
</document>
'::xml)
SELECT xpath('/document/pay/reqTransfer/source/card/bsc/text()', col) AS bsc
FROM x;
I get {}, but if I relpace the document start tag
<document xmlns="http://example.com/digital/back/" xmlns:ns2="http://example.com/digital/back/complexId" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="">
with <document> or even <document xmlns="">, I get { VISA } - that is right.
What should I do to replace <document xmlns="..."> with <document> or get { VISA } without replacement?
If you are working with XML namespaces, they are worth mentioning in your Xpath queries too, i.e. use
SELECT xpath('/d:document/d:pay/d:reqTransfer/d:source/d:card/d:bsc/text()', col,
ARRAY[ARRAY['d', 'http://example.com/digital/back/']]) AS bsc
http://sqlfiddle.com/#!17/9eecb/24719
See also:
how to ignore namespaces with XPath

How To Parse XDocument (Ebay) Items (List) Using Visual Basic?

<code>
For Each oXElement In oXDocument.Descendants("searchResult")
sTitle = oXElement.Element("title").Value
Next
</code>
I have also tried:
<code>
For Each oXElement In oXDocument.Elements(searchResults)
sTitle = oXElement.Element("title").Value
Next
</code>
I am having trouble getting a hold of nodes as well as understanding the way you communicate with XDocument nodes.
My Ultimate goal is to create an Ebay Object Model From all Ebay Element's Attributes. For that I need to refer to XML tag somehow - and this is where I would appreciate your advice or sample example that could let me proceed with parsing out this XML response.
Thank you all much for any help.
PS: I have searched for a similar questions and found a few of the same kind but still could not get my parsing to work.
<findItemsByProductResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<ack>Success</ack>
<version>1.12.0</version>
<timestamp>2013-06-02T22:42:04.500Z</timestamp>
<searchResult count="5">
<item>
<itemId>370821427802</itemId>
<title>
Modern Database Management 11E by Hoffer, Ramesh, Topi 11th (Int'l Edition)
</title>
<globalId>EBAY-US</globalId>
<primaryCategory>
<categoryId>2228</categoryId>
<categoryName>Textbooks, Education</categoryName>
</primaryCategory>
<galleryURL>
http://thumbs3.ebaystatic.com/m/meSAqCRbXecSjZjO1833dWQ/140.jpg
</galleryURL>
<viewItemURL>
http://www.ebay.com/itm/Modern-Database-Management-11E-Hoffer-Ramesh-Topi-11th-Intl-Edition-/370821427802?pt=US_Texbook_Education
</viewItemURL>
<productId type="ReferenceID">143649496</productId>
<paymentMethod>PayPal</paymentMethod>
<autoPay>true</autoPay>
<location>Malaysia</location>
<country>MY</country>
<shippingInfo>
<shippingServiceCost currencyId="USD">0.0</shippingServiceCost>
<shippingType>Free</shippingType>
<shipToLocations>Worldwide</shipToLocations>
<expeditedShipping>true</expeditedShipping>
<oneDayShippingAvailable>false</oneDayShippingAvailable>
<handlingTime>1</handlingTime>
</shippingInfo>
<sellingStatus>
<currentPrice currencyId="USD">54.07</currentPrice>
<convertedCurrentPrice currencyId="USD">54.07</convertedCurrentPrice>
<sellingState>Active</sellingState>
<timeLeft>P20DT10H47M20S</timeLeft>
</sellingStatus>
<listingInfo>
<bestOfferEnabled>false</bestOfferEnabled>
<buyItNowAvailable>false</buyItNowAvailable>
<startTime>2013-05-24T09:25:25.000Z</startTime>
<endTime>2013-06-23T09:29:24.000Z</endTime>
<listingType>StoreInventory</listingType>
<gift>false</gift>
</listingInfo>
<returnsAccepted>true</returnsAccepted>
<condition>
<conditionId>1000</conditionId>
<conditionDisplayName>Brand New</conditionDisplayName>
</condition>
<isMultiVariationListing>false</isMultiVariationListing>
<topRatedListing>true</topRatedListing>
</item>
<item>...</item>
<item>...</item>
<item>...</item>
<item>...</item>
</searchResult>
<paginationOutput>
<pageNumber>1</pageNumber>
<entriesPerPage>5</entriesPerPage>
<totalPages>3</totalPages>
<totalEntries>14</totalEntries>
</paginationOutput>
<itemSearchURL>
http://www.ebay.com/ctg/143649496?LH_BIN=1&_ddo=1&_incaucbin=0&_ipg=5&_pgn=1
</itemSearchURL>
</findItemsByProductResponse>
You have to use XNamespace instance when querying your XML:
Dim ns = XNamespace.Get("http://www.ebay.com/marketplace/search/v1/services")
And with that add it to every Descendants, Elements, Element, Attributes, Attributes, etc. calls you make:
For Each oXElement In oXDocument.Descendants(ns + "searchResult")
sTitle = oXElement.Element(ns + "title").Value
Next
For Each oXElement In oXDocument.Elements(ns + searchResults)
sTitle = oXElement.Element(ns + "title").Value
Next
Two things. First, you fell into the trap that catches 90% of the people with problems using LINQ to XML. You forgot the namespace. You can use the following which works in C# or VB:
Dim ns = XNamespace.Get("http://www.ebay.com/marketplace/search/v1/services")
VB Also lets you use a Imports for a namespace just as you import other .Net namespaces at the top of your file. The advantage of this option is that if you have a schema in your project, you get intellisense over the XML structure while building your query.
Imports <xmlns:eb="http://www.ebay.com/marketplace/search/v1/services">
The second issue you have is that the title element is not a direct child of searchResult, but is nested an additional level deeper. Here's a sample leveraging the imports for the namespace. I'm using the VB XML Literals for descendents (...) for contrast with anyone giving you a C# biased answer ;-)
Public Class XmlTest
Public Sub TestXml()
Dim data = <findItemsByProductResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<ack>Success</ack>
<version>1.12.0</version>
<timestamp>2013-06-02T22:42:04.500Z</timestamp>
<searchResult count="5">
<item>
<itemId>370821427802</itemId>
<title>
Modern Database Management 11E by Hoffer, Ramesh, Topi 11th (Int'l Edition)
</title>
<globalId>EBAY-US</globalId>
<primaryCategory>
<categoryId>2228</categoryId>
<categoryName>Textbooks, Education</categoryName>
</primaryCategory>
<galleryURL>
http://thumbs3.ebaystatic.com/m/meSAqCRbXecSjZjO1833dWQ/140.jpg
</galleryURL>
<viewItemURL>
http://www.ebay.com/itm/Modern-Database-Management-11E-Hoffer-Ramesh-Topi-11th-Intl-Edition-/370821427802?pt=US_Texbook_Education
</viewItemURL>
<productId type="ReferenceID">143649496</productId>
<paymentMethod>PayPal</paymentMethod>
<autoPay>true</autoPay>
<location>Malaysia</location>
<country>MY</country>
<shippingInfo>
<shippingServiceCost currencyId="USD">0.0</shippingServiceCost>
<shippingType>Free</shippingType>
<shipToLocations>Worldwide</shipToLocations>
<expeditedShipping>true</expeditedShipping>
<oneDayShippingAvailable>false</oneDayShippingAvailable>
<handlingTime>1</handlingTime>
</shippingInfo>
<sellingStatus>
<currentPrice currencyId="USD">54.07</currentPrice>
<convertedCurrentPrice currencyId="USD">54.07</convertedCurrentPrice>
<sellingState>Active</sellingState>
<timeLeft>P20DT10H47M20S</timeLeft>
</sellingStatus>
<listingInfo>
<bestOfferEnabled>false</bestOfferEnabled>
<buyItNowAvailable>false</buyItNowAvailable>
<startTime>2013-05-24T09:25:25.000Z</startTime>
<endTime>2013-06-23T09:29:24.000Z</endTime>
<listingType>StoreInventory</listingType>
<gift>false</gift>
</listingInfo>
<returnsAccepted>true</returnsAccepted>
<condition>
<conditionId>1000</conditionId>
<conditionDisplayName>Brand New</conditionDisplayName>
</condition>
<isMultiVariationListing>false</isMultiVariationListing>
<topRatedListing>true</topRatedListing>
</item>
<item>...</item>
<item>...</item>
<item>...</item>
<item>...</item>
</searchResult>
<paginationOutput>
<pageNumber>1</pageNumber>
<entriesPerPage>5</entriesPerPage>
<totalPages>3</totalPages>
<totalEntries>14</totalEntries>
</paginationOutput>
</findItemsByProductResponse>
For Each el In data...<eb:searchResult>
Console.WriteLine(el...<eb:title>.Value)
Next
End Sub
End Class

Linq to XML Insert a new element into the XML for each node

I would like to insert a new element in the following XML for each instance of a data node
Here is the initial XML that I have:
<dataCollection totalCount="12" pageCount="1">
<data>
<date>2011-11-10T00:00:00.000-05:00</date>
<dataType>PRCP</dataType>
<station>GHCND:USW00014739</station>
<value>267</value>
<address>
<home>X</home>
</address>
</data>
<data>
<date>2011-11-10T00:00:00.000-05:00</date>
<dataType>PRCP</dataType>
<station>GHCND:USW00014739</station>
<value>267</value>
<address>
<home>X</home>
</address>
</data>
</dataCollection>
And this is the XML I am trying to achieve
<dataCollection totalCount="12" pageCount="1">
<data>
<date>2011-11-10T00:00:00.000-05:00</date>
<dataType>TMIN</dataType>
<station>GHCND:USW00014739</station>
<value>267</value>
<newValue>60</newValue>
<address>
<home>X</home>
</address>
</data>
<data>
<date>2011-11-10T00:00:00.000-05:00</date>
<dataType>TMAX</dataType>
<station>GHCND:USW00014739</station>
<value>270</value>
<newValue>62</newValue>
<address>
<home>X</home>
</address>
</data>
</dataCollection>
The XML data is used as a data source for a DataGrid using the following Linq.
Dim elements = (From daDsc In xdoc.Descendants("data") _
Select Data_Type = daDsc.Element("dataType").Value, _
Raw_Value = daDsc.Element("value").Value,
newValue = daDsc.Element("newValue"))
Writing this in VB.net, but answers in C# is OK. Thanks.
Try this:
foreach (var xe in xml.Descendants("data"))
{
xe.Element("value")
.AddAfterSelf(new XElement("newValue", 42));
}
If you wish to add newValue into your XML before processing, you could do something like this:
For Each element As XElement In xml.Elements
element.SetElementValue("newValue", "something")
Next
where xml is an XDocument, loaded from your web service.

Linq To Xml - Unexpected search results

Just when I was thinking that I had Linq To Xml sussed I'm faced with yet another error! I think if I was to understand the linq search process in general better I might have more success, so any good links regarding that are also welcome. To my problem however; using the code below:
Dim xd As XDocument = _
<?xml version="1.0" encoding="utf-8"?>
<root>
<element>
<subelement id="1"/>
<subelement id="2"/>
<subelement id="3"/>
</element>
<element>
<subelement id="4"/>
<subelement id="1"/>
<subelement id="5"/>
</element>
</root>
Dim results = _
From q In xd.Descendants.<element> _
Where q.<subelement>.#id = 1
For Each xe As XElement In results
Console.WriteLine(xe.ToString)
Next
I would have expected the above code to return both 'element' nodes, but it only returns the first because it only searches the first 'subelement' node within 'element', how can I make the where clause apply to all 'subelement' nodes?
You could do
Dim results = _
From q In xd.Descendants.<element> _
From p In q.<subelement> _
Where p.#id = 1
(That is, if my VB.NET is up to the task here... I could do it in C#. Please feel free to edit.)