Linq to XML Insert a new element into the XML for each node - vb.net

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.

Related

how to delete empty namespace from child element in sql server

I am trying to delete empty namespace from the child element. I tried with following code but its not deleting
SET #xDocTemp.modify('declare default element namespace "mynamepsace";
delete /worksh/Data/row[#xmlns=""]')
xml data:
<worksh xmlns="mynamespace">
<Data>
<row r="1" ht="18">
<row xmlns="" rl="39" spans="2">
<row xmlns="" rl="39" spans="2">
</Data>
<worksh>
Expected output
<worksh xmlns="mynamespace">
<Data>
<row rl="1" ht="18">
<row rl="39" spans="2">
<row rl="39" spans="2">
</Data>
<worksh>
not sure if it's possible with modify(), but you can just replace it like
set #xDocTemp = select cast(replace(cast(#xDocTemp as nvarchar(max)), ' xmlns=""', '') as xml)

Adding namespace limits results Linq to XML

Ive read a few articles on Linq to XML and either ive picked it up wrong or missing some piece of the puzzle.
What im trying to achieve is to load some XML, get required data by different named fields and nodes/elements. Here is the XML
<?xml version="1.0" encoding="utf-8"?>
<metadata created="2014-05-15T12:26:07.701Z" xmlns="http://site/cu-2.0#" xmlns:ext="http://site/cu/b-2.0">
<customer-list count="47" offset="0">
<customer id="7123456" type="Cust" ext:mark="1">
<name>Tony Watt</name>
<sort-name>Watt, Tony</sort-name>
<gender>male</gender>
<country>US</country>
<knownAs-list>
<knownAs locale="ko" sort-name="Tony Watt"</knownAs>
<knownAs locale="ja" sort-name="Watt Tony"</knownAs>
</knownAs-list>
</customer>
<tag-list>
<tag count="1">
<name>Country</name>
</tag>
<tag count="1">
<name>usa</name>
</tag>
<customer id="9876543" type="Cust" ext:mark="2">
So i can load the XML and i can display data. Heres a snippet of the code
Dim ns As XNamespace = "http://site/cu-2.0#"
Dim XDoc As XDocument = XDocument.Parse(SomeXML)
For Each c As XElement In XDoc.Descendants(ns + "name")
Response.Write(c)
Next
So this displays all the elements with "name". The problem i have here is i want the customer name but not the tag-list country name (see last few lines of the XML)
Ideally i want to return all the details for each customer but adding the namespace limits the me to all the elements with name when i want other data too. If i remove the namespace i get no results returned so im unsure what to do next?
Ive read a ton of articles but i cant seem to work out what needs to be done or if ive gone down the wrong path? Please remember i have tried other methods which i can post if anyone likes but after reading MSDN and other articles i think ive confused myself or missed out a step.
I think you simply want to use
Dim ns As XNamespace = "http://site/cu-2.0#"
Dim XDoc As XDocument = XDocument.Parse(SomeXML)
For Each c As XElement In XDoc.Descendants(ns + "customer")
Response.Write(c.Element(ns + "name").Value)
Next
If you are trying to get name from customer give this a try
Dim xe As XElement =
<customer-list count="47" offset="0">
<customer id="7123456" type="Cust" mark="1">
<name>Tony Watt</name>
<sort-name>Watt, Tony</sort-name>
<gender>male</gender>
<country>US</country>
<knownAs-list>
<knownAs locale="ko" sort-name="Tony Watt"></knownAs>
<knownAs locale="ja" sort-name="Watt Tony"></knownAs>
</knownAs-list>
</customer>
<customer id="1" type="Cust" mark="1">
<name>Fred Flintstone</name>
<sort-name>Flintstone, Fred</sort-name>
<gender>male</gender>
<country>US</country>
<knownAs-list>
<knownAs locale="ko" sort-name="Fred Flintstone"></knownAs>
<knownAs locale="ja" sort-name="Flintstone Fred"></knownAs>
</knownAs-list>
</customer>
<tag-list>
<tag count="1">
<name>Country</name>
</tag>
<tag count="1">
<name>usa</name>
</tag>
</tag-list>
</customer-list>
Dim ie As IEnumerable(Of XElement) = From c As XElement In xe.Elements
Where c.Name.LocalName = "customer"
Select c From n As XElement In c.Elements
Where n.Name.LocalName = "name" Select n
For Each r As XElement In ie
Debug.WriteLine(r.Value)
Next

Been trying to write an xquery code that converts a flat xml to 5-level hierarchy xml file

Would like to convert the following flax xml file to 5-level hierarchy xml structure using xquery, so far the all the xquery code i have written did not work.
<data>
<row>
<Year>1999</Year>
<Quarter>8</Quarter>
<Month>5</Month>
<Week>10</Week>
<Flight>6/11/1995</Flight>
<Un>WN</Un>
<Air>193</Air>
</row>
<data>
Out result i would like:
<data>
<row>
<Year>
<value>1999</value>
<Quarter>
<value>8</value>
<Month>
<value>5</value>
<Week>10</Week>
<Flight>6/11/1995</Flight>
<Un>WN</Un>
<Air>193</Air>
</Month>
</Quarter>
</Year>
</row>
<data>
It's unclear what XQuery processor you're using, or the exact schema of the data you will need to process, but here is an example of how to transform the data, assuming each row contains a unique set of entries:
let $data :=
<data>
<row>
<Year>1999</Year>
<Quarter>8</Quarter>
<Month>5</Month>
<Week>10</Week>
<Flight>6/11/1995</Flight>
<Un>WN</Un>
<Air>193</Air>
</row>
</data>
for $row in $data/row
return
element row {
element Year {
element value { $row/Year/data() },
element Quarter {
element value { $row/Quarter/data() },
element Month {
element value { $row/Month/data() },
$row/Week,
$row/Flight,
$row/Un,
$row/Air
}
}
}
}
If you want a single element for each year/quarter/month, use this code:
<data>
<row>{
for $year in //row/Year/data()
return
<Year>{
<value>{ $year }</value>,
for $quarter in //row[Year=$year]/Quarter/data()
return
<Quarter>{
<value>{ $quarter }</value>,
for $row in //row[Year=$year and Quarter=$quarter]
return
<Month>{
<value>{ Month/data() }</value>,
$row/*[not(local-name(.) = ('Month', 'Quarter', 'Year'))]
}</Month>
}</Quarter>
}</Year>
}</row>
</data>

LINQ to XML , retrieving data

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

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.)