i need to xml file repeated item. Inside "item" i have fields like title, pubdate, description, dc:creator and with repeatwp:comment... see the xml file below..
<channel>
<item>
<title>What Messed With My Head: Summit 2011</title>
<link>http://www.wcablog.com/2011/08/what-messed-with-my-head-summit-2011/</link>
<pubDate>Fri, 26 Aug 2011 09:10:04 +0000</pubDate>
<dc:creator>willowcreekassociation</dc:creator>
<guid isPermaLink="false">http://www.wcablog.com/?p=1706</guid>
<description></description>
<content:encoded>
<![CDATA[text here]]>
</content:encoded>
<wp:comment>
<wp:comment_id>1016</wp:comment_id>
<wp:comment_author><![CDATA[]]></wp:comment_author>
<wp:comment_author_email>thelmabowlen#gmail.com</wp:comment_author_email>
<wp:comment_author_url></wp:comment_author_url>
<wp:comment_author_IP></wp:comment_author_IP>
<wp:comment_date>2011-08-26 20:13:00</wp:comment_date>
<wp:comment_content><![CDATA[some text ]]></wp:comment_content>
</wp:comment>
<wp:comment>
<wp:comment_id>1016</wp:comment_id>
<wp:comment_author><![CDATA[]]></wp:comment_author>
<wp:comment_author_email>thelmabowlen#gmail.com</wp:comment_author_email>
<wp:comment_author_url></wp:comment_author_url>
<wp:comment_author_IP></wp:comment_author_IP>
<wp:comment_date>2011-08-26 20:13:00</wp:comment_date>
<wp:comment_content><![CDATA[some text ]]></wp:comment_content>
</wp:comment>
</item>
<item>
<title>What Messed With My Head: Summit 2011</title>
<link>http://www.wcablog.com/2011/08/what-messed-with-my-head-summit-2011/</link>
<pubDate>Fri, 26 Aug 2011 09:10:04 +0000</pubDate>
<dc:creator>willowcreekassociation</dc:creator>
<guid isPermaLink="false">http://www.wcablog.com/?p=1706</guid>
<description></description>
<content:encoded>
<![CDATA[text here]]>
</content:encoded>
</item>
<item>
<title>What Messed With My Head: Summit 2011</title>
<link>http://www.wcablog.com/2011/08/what-messed-with-my-head-summit-2011/</link>
<pubDate>Fri, 26 Aug 2011 09:10:04 +0000</pubDate>
<dc:creator>willowcreekassociation</dc:creator>
<guid isPermaLink="false">http://www.wcablog.com/?p=1706</guid>
<description></description>
<content:encoded>
<![CDATA[text here]]>
</content:encoded>
<wp:comment></wp:comment>
<wp:comment></wp:comment>
</item>
</channel>
I am using following code to read xml..
XDocument xDoc = XDocument.Load("willowcreekassociationblog.wordpress.xml");
var list = xDoc.Descendants("Occurrence")
.Select(o => new List.XMLList
{
title = (string)o.Element("title"),
URL = (string)o.Element("link"),
Descr = (string)o.Element("Description"),
StartDate = (DateTime)o.Element("pubdate"),
})
.ToList();
But i dont know how read the wp:comment with my above code...can anyone help me how to do this??
You haven't said what you want to do with the data, which makes the question hard to answer. You also haven't shown where the wp namespace alias is defined, but hey...
You want something like this, within your Select call:
Comments = o.Elements(wp + "comment")
.Select(comment => Comment.FromXElement(comment))
.ToList();
I find it helpful to give static methods within the domain objects which can perform the transformation from XElement - it keeps things clearer.
FromXElement would then be something like:
public static Comment FromXElement(XElement x)
{
return new Comment((int) x.Element(wp + "comment_id"),
(string) x.Element(wp + "author"),
...);
}
Related
I read multiple feed from many sources with C# Console, and i have this code where i load XML From sources:
XmlDocument doc = new XmlDocument();
doc.Load(sourceURLX);
XElement xdoc = XElement.Load(sourceURLX);
How to get enclosure url and show as variable?
If I understand your question correctly (I'm making a big assumption here) - you want to select an attribute from the root (or 'enclosing') tag, named 'url'?
You can make use of XPath queries here. Consider the following XML:
<?xml version="1.0" encoding="utf-8"?>
<root url='google.com'>
<inner />
</root>
You could use the following code to retrieve 'google.com':
String query = "/root[1]/#url";
XmlDocument doc = new XmlDocument();
doc.Load(sourceURLX);
String value = doc.SelectSingleNode(query).InnerText;
Further information about XPath syntax can be found here.
Edit: As you stated in your comment, you are working with the following XML:
<item>
<description>
</description>
<enclosure url="blablabla.com/img.jpg" />
</item>
Therefore, you can retrieve the url using the following XPath query:
/item[1]/enclosure[1]/#url
With xml like below
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>title</title>
<link>https://www.link.com</link>
<description>description</description>
<item>
<title>RSS</title>
<link>https://www.link.com/xml/xml_rss.asp</link>
<description>description</description>
<enclosure url="https://www.link.com/media/test.wmv"
length="10000"
type="video/wmv"/>
</item>
</channel>
</rss>
You will get url by reading attribute
var document = XDocument.Load(sourceURLX);
var url = document.Root
.Element("channel")
.Element("item")
.Element("enclosure")
.Attribute("url")
.Value;
To get multiple urls
var urls = document.Descendants("item")
.Select(item => item.Element("enclosure").Attribute("url").Value)
.ToList();
Using foreach loop
foreach (var item in document.Descendants("item"))
{
var title = item.Element("title").Value;
var link = item.Element("link").Value;
var description = item.Element("description").Value;
var url = item.Element("enclosure").Attribute("url").Value;
// save values to database
}
//assume that I have the following XML file.
<warehouse>
<cat id="computer">
<item>
<SN>1</SN>
<name>Toshiba</name>
<quantity>12</quantity>
<description>CPU: CORE I5 RAM: 3 GB HD: 512 GB</description>
<price>400 USD</price>
</item>
<item>
<SN>22</SN>
<name>Toshiba</name>
<quantity>12</quantity>
<description>CPU: CORE I5 RAM: 3 GB HD: 512 GB</description>
<price>400 USD</price>
</item>
</cat>
<cat id="Stationery">
<item>
<SN> 33 </SN>
<name>note books</name>
<quantity>250</quantity>
<description>Caterpiller</description>
<price>5 USD</price>
</item>
</cat>
<cat id="Furniture">
<item>
<SN> 1 </SN>
<name>dasd</name>
<quantity>asdasd</quantity>
<description>das</description>
<price>dasd</price>
</item>
<item>
<SN>44</SN>
<name>Toshiba</name>
<quantity>12</quantity>
<description>CPU: CORE I5 RAM: 3 GB HD: 512 GB</description>
<price>400 USD</price>
</item>
<item>
</cat>
</warehouse>
question 1 : I want to Delete <item> element and its child's using linq , where <cat id="computer"> and <SN> has a specific value like 44 .
question 2 : I want to make a query using TextBox and Literal1 which return a specic <item> and its child's . this query should be in linq.
for example
XDocument xmlDoc = XDocument.Load(Server.MapPath("/XML/Cat1.xml"));
var persons = from person in xmlDoc.Descendants("item")
where person.Element("SN").Value.Equals(DropDownList1.Text)
select person;
persons.Remove();
foreach (XElement person in persons.ToList())
{
person.Remove();
}
Try this:-
xmlDoc.Root.Descendants("cat").Where(x => x.Attribute("id").Value == "computer")
.Descendants("item").Where(x => x.Element("SN").Value.Trim() == Dropdownlist.Text)
.Remove();
xmlDoc.Save(#"YourXML.xml");
And for filtering you can replace the values at specific places you like. Also, I have used Trim directly, better check for empty strings first in your actual code.
Question 2:-
var result = xmlDoc.Descendants("item")
.Where(x => x.Element("SN").Value.Trim() == Dropdownlist.Text);
Regarding question one i would do something like this using method syntax:
doc.Descendants("cat")
.Where(x => String.Equals((string)x.Attribute("id"), "computer", StringComparison.OrdinalIgnoreCase))
.Elements("item")
.Where(x => (string)x.Element("SN") == "44")
.Remove();
Basically select all your cat elements and filter by attribute id = computer. Then select all items in each of those and filter through SN = 44.
I am using c# to read (attempting to) an RSS feed, but I am getting an error "Namespace prefix 'cb' is not defined" , I am pretty new to XML and C# and was hoping for some help, I read a bit on creating the Namespace but I am not 100% sure I am grasping it.
Any help would be greatly appreciated.
The C# code is:
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
// Create an XmlNamespaceManager to resolve the default namespace.
XmlDocument xm = new XmlDocument();
xm.Load(Variables.USFeed.ToString());
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xm.NameTable);
nsmgr.AddNamespace("rdf", "http://purl.org/rss/1.0/");
XmlNodeList xnode = xm.GetElementsByTagName("item");
foreach (XmlNode xmn in xnode)
{
XmlElement currencyElement = (XmlElement)xmn;
if (currencyElement.HasAttribute("rdf:about"))
{
Output0Buffer.AddRow();
Output0Buffer.observationPeriod = currencyElement.SelectSingleNode("cb:statistics/cb:exchangeRate/cb:observationPeriod", nsmgr).InnerText;
Output0Buffer.targetCurrency = currencyElement.SelectSingleNode("cb:statistics/cb:exchangeRate/cb:targetCurrency", nsmgr).InnerText;
Output0Buffer.baseCurrency = currencyElement.SelectSingleNode("cb:statistics/cb:exchangeRate/cb:baseCurrency", nsmgr).InnerText;
Output0Buffer.exchangeRate = double.Parse(currencyElement.SelectSingleNode("cb:statistics/cb:exchangeRate/cb:value", nsmgr).InnerText);
}
}
and the summarized version of the rss is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3c.org/1999/02/22-rdf-syntax-ns#rdf.xsd">
<channel rdf:about="http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_ALL.xml">
<title xml:lang="en">Bank of Canada: Noon Foreign Exchange Rates</title>
<link>http://www.bankofcanada.ca/rates/exchange/noon-rates-5-day/</link>
<description>Current day's noon foreign exchange rates from the Bank of Canada. Published at about 12:15 ET.</description>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_USD.xml" />
<rdf:li rdf:resource="http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_VEF.xml" />
<rdf:li rdf:resource="http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_VND.xml" />
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_USD.xml">
<title xml:lang="en">CA: 0.9382 USD = 1 CAD 2014-01-06 Bank of Canada noon rate</title>
<cb:statistics>
<cb:country>CA</cb:country>
<cb:exchangeRate>
<cb:value decimals="4">0.9382</cb:value>
<cb:baseCurrency>CAD</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Bank of Canada noon rate</cb:rateType>
<cb:observationPeriod frequency="daily">2014-01-06T12:15:00-05:00</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_ARS.xml">
<title xml:lang="en">CA: 6.1843 ARS = 1 CAD 2014-01-06 Bank of Canada noon rate</title>
<cb:statistics>
<cb:country>CA</cb:country>
<cb:exchangeRate>
<cb:value decimals="4">6.1843</cb:value>
<cb:baseCurrency>CAD</cb:baseCurrency>
<cb:targetCurrency>ARS</cb:targetCurrency>
<cb:rateType>Bank of Canada noon rate</cb:rateType>
<cb:observationPeriod frequency="daily">2014-01-06T12:15:00-05:00</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
You need to add "cb" to your XmlNamespaceManager in order to use "cb" in SelectSingleNode.
nsmgr.AddNamespace(
"cb",
"http://www.cbwiki.net/wiki/index.php/Specification_1.1");
I googled for hours and didn't find anything.
I'm trying to make a Metro App which is reading from an online XML Service. Getting the XML is not the problem, i'm simply doing it like this ->
var xmlDoc = await XmlDocument.LoadFromUriAsync(new Uri(url));
but now the problem is, how to convert it into a list or something readable like this.
The XML I want to read is really huge and i don't want to go through all nodes with foreach.
A simple Array/List with all nodes and innerText as Value would be awesome.
Is this possible? If yes.. how ?
The structure of my XML is like this ->
<?xml version="1.0" encoding="UTF-8"?>
<city>
...
<credit>
...
</credit>
<forecast>
<date value="2013-11-08">
...
<time value="06:00">
...
</time>
<time value="11:00">
...
</time>
<time value="17:00">
...
</time>
<time value="23:00">
...
</time>
...
</date>
<date value="2013-11-09">
<same content here>
</date>
<date value="2013-11-09">
<same content here>
</date>
</forecast>
</city>
as you can see... there's a lot of information in the XML and I need nearly everything. In Actionscript I would realize it with a XMLList and make 3 Lists of the date Tags with content, so i can use
xmllist1.time[0] - xmllist1.time[3]
xmllist2.time[0] - xmllist2.time[3]
xmllist3.time[0] - xmllist3.time[3]
to get my data.
And now i want this XMLList in C#... I hope it's possible...Thx 4 help
If I understand you correctly, you want to parse the list of "city" items from the xml.
I do something similar using XDocument and Linq like this and it should work for you:
XDocument xdoc = <add your code to get xml from url>;
var ns = xdoc.Root.GetDefaultNamespace();
var cityList = from query in xdoc.Descendants(ns + "city")
select new CityItem
{
Date = (string)query.Element(ns + "date").Attribute("value").Value,
Time = (string)query.Element(ns + "time").Attribute("value").Value
};
public class CityItem
{
public string Date {get;set;}
public string Time {get;set;}
}
I have an input RSS Feed with some elements already added with namespace prefix (for itunes). Without removing attribute and adding in C# again, an element, say <itunes:subtitle> is added as namespace and the element is <subtitle>
Desired output:
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd/" version="2.0">
<channel>
<title>channelTitle</title>
<itunes:subtitle>subtitle_description</itunes:subtitle>
<item>
<title>item1</title>
<itunes:subtitle>A short description</itunes:subtitle>
</item>
</channel>
</rss>
Input XML:
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd/" version="2.0">
<channel>
<item>
<title>item1</title>
<itunes:subtitle>A short description</itunes:subtitle>
</item>
</channel>
</rss>
How can I add another element in C#, but also maintain the existing namespace:element ? I'm having to explicitly add the namespace again in the code (and namespace should also be present in input XML, otherwise it's processing invalid XML:
See code:
XNamespace itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd/";
string rssFeed = "<rss xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" version=\"2.0\"><channel><item><title>item1</title><itunes:subtitle>A short description</itunes:subtitle></item></channel></rss>";
XDocument XMLDoc = XDocument.Parse(rssFeed);
XMLDoc.Root.RemoveAttributes();
XMLDoc.Root.Add(new XAttribute(XNamespace.Xmlns + "itunes", itunes.NamespaceName));
//Without adding the namespace attribute explicitly, the xmlns attribute is added instead to <subtitle> instead of <itunes:subtitle> :
XMLDoc.Element("rss").Element("channel").AddFirst(
new XElement("title", "channelTitle"),
new XElement(itunes + "subtitle", "subtitle_description")
);
gets added correctly.
However, is now changed in the input XML, output:
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd/">
<channel>
<title>channelTitle</title>
<itunes:subtitle>subtitle_description</itunes:subtitle>
<item>
<title>item1</title>
<subtitle xmlns="http://www.itunes.com/dtds/podcast-1.0.dtd">A short description</subtitle>
</item>
</channel>
</rss>
Approach2:
XNamespace itunes = "http://www.itunes.com/dtds/podcast-1.0.dtd/";
string rssFeed = "<rss xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" version=\"2.0\"><channel><item><title>item1</title><itunes:subtitle>A short description</itunes:subtitle></item></channel></rss>";
XDocument XMLDoc = XDocument.Parse(rssFeed);
XMLDoc.Element("rss").Element("channel").AddFirst(
new XElement("title", "channelTitle"),
new XElement(itunes + "subtitle", "subtitle_description")
);
Console.WriteLine(XMLDoc);
Output:
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
<channel>
<title>channelTitle</title>
<subtitle xmlns="http://www.itunes.com/dtds/podcast-1.0.dtd/">subtitle_description</subtitle>
<item>
<title>item1</title>
<itunes:subtitle>A short description</itunes:subtitle>
</item>
</channel>
</rss>
As much as my question is really long, I'm hoping to get few lines of code as an answer, sure there must be something simple I'm missing :)
I can't reproduce the problem you say you face, the following straightforward sample
string rssFeed = "<rss xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" version=\"2.0\"><channel><item><title>item1</title><itunes:subtitle>A short description</itunes:subtitle></item></channel></rss>";
XDocument XMLDoc = XDocument.Parse(rssFeed);
XNamespace itunes = XMLDoc.Root.GetNamespaceOfPrefix("itunes");
XMLDoc.Element("rss").Element("channel").AddFirst(
new XElement("title", "channelTitle"),
new XElement(itunes + "subtitle", "subtitle_description")
);
XMLDoc.Save(Console.Out);
Console.WriteLine();
when run with .NET 3.5, outputs
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
<channel>
<title>channelTitle</title>
<itunes:subtitle>subtitle_description</itunes:subtitle>
<item>
<title>item1</title>
<itunes:subtitle>A short description</itunes:subtitle>
</item>
</channel>
</rss>
Looking closer at your code, the only problem is see is that some samples use the URI http://www.itunes.com/dtds/podcast-1.0.dtd while some have http://www.itunes.com/dtds/podcast-1.0.dtd/ with a trailing slash "/". So that might be the reason why you run into problems.