ASP.NET C# Write RSS feed for Froogle - c#

I'm trying to create a RSS 2.0 feed in ASP.NET C# with products to provide to Froogle.
The RSS feed should look like:
http://www.google.com/support/merchants/bin/answer.py?answer=160589&hl=en
I'm using the SyndicationFeed and SyndicationsItems to create the feed. But I'm having trouble adding the extra elements like g:image_link.
I try the extra elements like;
syndicationItem.ElementExtensions.Add(new XElement("image_link", product.ImageLink).CreateReader());
This works, but how can I add the namespace
xmlns:g="http://base.google.com/ns/1.0"
to the first RSS tag and use this for the extension elements?
Thank you

I just wrote something like this last week, as a matter of fact. I didn't have much time, so it's not optimized or pretty.
I used an XDocument, though.
static XDocument GetXDocument(List<GoogleProduct> googleProducts)
{
XNamespace gns = "http://base.google.com/ns/1.0";
XDocument document = new XDocument(
new XElement("rss",
new XAttribute("version", "2.0"),
new XAttribute(XNamespace.Xmlns + "g", gns),
new XElement("channel",
new XElement("title", "X Company Feed"),
new XElement("description", "X Description"),
new XElement("link", "http://www.somecompany.com/"),
from googleProduct in googleProducts
select new XElement("item",
new XElement("title", googleProduct.Title),
new XElement(gns + "brand", googleProduct.ProductRecommendedAttributes.Brand),
new XElement(gns + "manufacturer", googleProduct.ProductRecommendedAttributes.Manufacturer),
new XElement(gns + "condition", googleProduct.Condition),
new XElement("description", googleProduct.Description),
new XElement(gns + "id", googleProduct.ID),
from img in googleProduct.ProductRecommendedAttributes.ImageLinks
select new XElement(gns + "image_link", img),
new XElement("link", googleProduct.Link),
new XElement(gns + "price", googleProduct.Price.ToString("0.00")),
new XElement(gns + "product_type", googleProduct.ProductRecommendedAttributes.ProductType),
from pmt in googleProduct.ProductOptionalAttributes.PaymentAccepteds
select new XElement(gns + "payment_accepted", pmt)))));
//
return document;
}
(FYI: GoogleProduct is just a temporary mapper class I used)
It will generate a document along these lines
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>Blah Data Feed</title>
<description>Stuff from Blah</description>
<link>http://www.blah.com/shopping</link>
<item>
<title>Blah</title>
<g:brand>Blah</g:brand>
<g:manufacturer>Blah</g:manufacturer>
<g:condition>New</g:condition>
<description>blah blah</description>
<g:id>268</g:id>
<g:image_link>http://www.blah.com/shopping/images/PRODUCT/medium/268.jpg</g:image_link>
<link>http://www.blah.com/</link>
<g:price>1747.00</g:price>
<g:product_type>Blah Blah</g:product_type>
<g:payment_accepted>Cash</g:payment_accepted>
<g:payment_accepted>Check</g:payment_accepted>
<g:payment_accepted>Visa</g:payment_accepted>
<g:payment_accepted>Mastercard</g:payment_accepted>
</item>
<item>
<title>Blah</title>
<g:brand>Blah</g:brand>
<g:manufacturer>Blah</g:manufacturer>
<g:condition>New</g:condition>
<description>blah blah</description>
<g:id>269</g:id>
<g:image_link>http://www.blah.com/shopping/images/PRODUCT/medium/269.jpg</g:image_link>
<link>http://www.blah.com/</link>
<g:price>1103.00</g:price>
<g:product_type>blah blah</g:product_type>
<g:payment_accepted>Cash</g:payment_accepted>
<g:payment_accepted>Check</g:payment_accepted>
<g:payment_accepted>Visa</g:payment_accepted>
<g:payment_accepted>Mastercard</g:payment_accepted>
</item>
</channel>
</rss>

XElements have great namespace support. Create your first element like this:
XNamespace aw = "http://base.google.com/ns/1.0";
XElement root = new XElement(aw + "image_link", product.ImageLink);
This will give you XML like this:
<image_link xmlns="http://base.google.com/ns/1.0">
</image_link>
Each subsequent element should also use the same namespace. If you want to use namespace prefixes for your elements, it's a similar approach. You can check out some full examples on MSDN here:
How to: Create a Document with Namespaces

Related

Using LINQ to output SQL data from two tables into XML

i am very new to this. Hope someone could help me suggest how to improve the code.
I have two tables where i need to get the SQL data and ouput it into XML format. I am using LINQ method. Below how the code looks like.
#region Database XML Methods
private static void CreateDatabaseXml(string path)
{
tbchrDataContext db = new tbchrDataContext();
XDocument doc = new XDocument(
// XML Declaration
new XDeclaration("1.0", "utf-8", "yes"),
// XML Root element to 3rd in nest
new XElement(ns + "WMS",
new XElement(ns + "Order",
new XElement(ns + "Header", from a in db.T_ORDER_DETAILs
select new XElement(ns + "RARefNum", a.RARefNum),
new XElement (ns + "WMSCategory", from b in db.T_ORDER_HEADERs select b.Customer),
new XElement (ns + "CustomerID", from a in db.T_ORDER_DETAILs select a.SupplierName)))) );
#endregion
doc.Save(path);
}
And below how is the output of XML looks like.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<WMS xmlns="http://blog.cripperz.sg">
<Order>
<Header>
<RARefNum>RASO000001</RARefNum>
<RARefNum>RASO000001</RARefNum>
<WMSCategory>ESSVMI</WMSCategory>
<CustomerID>nVidianVidia</CustomerID>
</Header>
</Order>
</WMS>
Ultimately i wanted to achieve the below XML, some of the data grab from SQL is from two separate tables in one XML nest / element.
<?xml version="1.0" encoding="utf-8"?>
<WMS>
<Order>
<Header>
<RARefNum>RASO000001</RARefNum>
<WMSCategory>ESSVMI</WMSCategory>
<CustomerID>nVidia</CustomerID>
<CreationDate>2013-12-02 06:29:50</CreationDate>
<OrderDate>2013-12-02 06:29:50</OrderDate>
<ExpectedShippedDate>2013-12-02 06:29:50</ExpectedShippedDate>
<LastShippedDate>2013-12-02 06:29:50</LastShippedDate>
<CustomerOrderReference>nVidia9338</CustomerOrderReference>
<CustomerShipmentNo>81475721</CustomerShipmentNo>
<CustomerSONo>SO982733</CustomerSONo>
<CustomerInvoiceNo>INV987373</CustomerInvoiceNo>
<CustomerReference1>nVidia 1</CustomerReference1>
<CustomerReference2/>
<WMSReference1>Emp 1</WMSReference1>
<WMSReference2>Emp 2</WMSReference2>
<ShipmentNo>IWU997872</ShipmentNo>
<DocumentNo>KK98764394</DocumentNo>
<Transportation>
<Mode>Freight</Mode>
<VehicleType/>
</Transportation>
<Carrier>
<ID>Fedex</ID>
<Name>Fedex SG</Name>
<Address>Changi Singapore</Address>
<Country/>
<PostalCode/>
<Contact>
<Sequence/>
<Person/>
<Email/>
<DID/>
<Handphone/>
</Contact>
</Carrier>
<Consignee>
<ID>ABC</ID>
<Name>ABC Corp</Name>
<Address>Jurong West, Singapore</Address>
<Country/>
<PostalCode/>
<Contact>
<Sequence/>
<Person/>
<Email/>
<DID/>
<Handphone/>
</Contact>
</Consignee>
<Containers/>
</Header>
<Details>
<Detail>
<LineNo>1</LineNo>
<SKU>SKU0001</SKU>
<SKUDescription>SKU 0001</SKUDescription>
<Package>50</Package>
<OrderedQty>600.000</OrderedQty>
<PickedQty>600.000</PickedQty>
<PickedDate>2013-12-02 06:35:09</PickedDate>
<ShippedQty>600.000</ShippedQty>
<ShippedDate>2013-12-02 06:35:09</ShippedDate>
<ManufactoryDate>2013-12-02 06:35:09</ManufactoryDate>
<ExpiryDate>2014-12-02 06:35:09</ExpiryDate>
<FIFODate>2013-06-02 06:35:09</FIFODate>
<CustomerLotRef1>nVidia 2093</CustomerLotRef1>
<CustomerLotRef2>nVidia 2099</CustomerLotRef2>
<LineReference1>10</LineReference1>
</Detail>
<Detail>
<LineNo>2</LineNo>
<SKU>SKU0002</SKU>
<SKUDescription>SKU 0002</SKUDescription>
<Package>50</Package>
<OrderedQty>100.000</OrderedQty>
<PickedQty>100.000</PickedQty>
<PickedDate>2013-12-02 06:35:09</PickedDate>
<ShippedQty>100.000</ShippedQty>
<ShippedDate>2013-12-02 06:35:09</ShippedDate>
<ManufactoryDate>2013-12-02 06:35:09</ManufactoryDate>
<ExpiryDate>2014-12-02 06:35:09</ExpiryDate>
<FIFODate>2013-06-02 06:35:09</FIFODate>
<CustomerLotRef1>nVidia 2193</CustomerLotRef1>
<CustomerLotRef2>nVidia 2199</CustomerLotRef2>
<LineReference1>10</LineReference1>
</Detail>
</Details>
</Order>
</WMS>
Is there a better way to code it?
In sql server support lot of xml format outputs.
This query returns a xml document from two tables. Maybe you are using
linq, then after completing your sql query, you execute the query from
linq.
select table1.column1, table2.column2 from table1 inner join table2 on table2.table1_id = table1.Id for xml auto
Check this link.
I dont know if this is better but I would probably make some variables instead of calling the linq in the xml. Then you can just call the variable in the xml document.
Something like this maybe:
private static void CreateDatabaseXml(string path)
{
tbchrDataContext db = new tbchrDataContext();
var rARefNum = db.T_ORDER_DETAILs.Select(i => i.RARefNum).Single();
var customer = db.T_ORDER_HEADERs.Select(i => i.Customer).Single();
var supplierName = db.T_ORDER_DETAILs.Select(i => i.SupplierName).Single();
XDocument doc = new XDocument(
// XML Declaration
new XDeclaration("1.0", "utf-8", "yes"),
// XML Root element to 3rd in nest
new XElement(ns + "WMS",
new XElement(ns + "Order",
new XElement(ns + "Header", new XElement(ns + "RARefNum", rARefNum),
new XElement (ns + "WMSCategory", customer),
new XElement (ns + "CustomerID", supplierName)))) );
#endregion
doc.Save(path);
}

Adding child nodes using c# Xdocument class

I have an xml file as given below.
<?xml version="1.0" encoding="utf-8"?>
<file:Situattion xmlns:file="test">
<file:Properties>
</file:Situattion>
I would like to add the child element file:Character using xDocument.So that my final xml would be like given below
<?xml version="1.0" encoding="utf-8"?>
<file:Situattion xmlns:file="test">
<file:Characters>
<file:Character file:ID="File0">
<file:Value>value0</file:Value>
<file:Description>
Description0
</file:Description>
</file:Character>
<file:Character file:ID="File1">
<file:Value>value1</file:Value>
<file:Description>
Description1
</file:Description>
</file:Character>
</file:Characters>
Code in c# i tried using Xdocument class is given below.
XNamespace ns = "test";
Document = XDocument.Load(Folderpath + "\\File.test");
if (Document.Descendants(ns + "Characters") != null)
{
Document.Add(new XElement(ns + "Character"));
}
Document.Save(Folderpath + "\\File.test");
At line "Document.Add(new XElement(ns + "Character"));", I am getting an error:
"This operation would create an incorrectly structured document.".
How can I add the node under "file:Characters".
You're trying to add an extra file:Character element directly into the root. You don't want to do that - you want to add it under the file:Characters element, presumably.
Also note that Descendants() will never return null - it will return an empty sequence if there are no matching elements. So you want:
var ns = "test";
var file = Path.Combine(folderPath, "File.test");
var doc = XDocument.Load(file);
// Or var characters = document.Root.Element(ns + "Characters")
var characters = document.Descendants(ns + "Characters").FirstOrDefault();
if (characters != null)
{
characters.Add(new XElement(ns + "Character");
doc.Save(file);
}
Note that I've used more conventional naming, Path.Combine, and also moved the Save call so that you'll only end up saving if you've actually made a change to the document.
Document.Root.Element("Characters").Add(new XElement("Character", new XAttribute("ID", "File0"), new XElement("Value", "value0"), new XElement("Description")),
new XElement("Character", new XAttribute("ID", "File1"), new XElement("Value", "value1"), new XElement("Description")));
Note: I have not included the namespace for brevity. You have to add those.

LINQ Writing HTML as XML

I am new to web programming and Visual Web Developer. I have made a page that prompts the user for input and then this input replaces the prompts using InnerHTML accesses. Thus the table can only be edited the first time it is displayed. It is the final, edited version of the HTML that I want others to be able to access. So I need a way to write the edits out to an XML file. I understand that this can be done with LINQ but I haven't figured out how to do it.
Any advice is appreciated.
Regards.
Here's an example I found online at: http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx. You should be able to figure it out if you compare the LINQ to XML code with the file output.
Code:
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("rss",
new XAttribute("version", "2.0"),
new XElement ("channel",
new XElement("title", "RSS Channel Title"),
new XElement("description", "RSS Channel Description."),
new XElement("link", "http://aspiring-technology.com"),
new XElement("item",
new XElement("title", "First article title"),
new XElement("description", "First Article Description"),
new XElement("pubDate", DateTime.Now.ToUniversalTime()),
new XElement("guid", Guid.NewGuid())),
new XElement("item",
new XElement("title", "Second article title"),
new XElement("description", "Second Article Description"),
new XElement("pubDate", DateTime.Now.ToUniversalTime()),
new XElement("guid", Guid.NewGuid()))
)
)
);
doc.Save(#"c:\sample.xml");
file:
<rss version="2.0">
<channel>
<title>RSS Channel Title</title>
<description>RSS Channel Description.</description>
<link>http://aspiring-technology.com</link>
<item>
<title>First article title</title>
<description>First Article Description</description>
<pubDate>2006-12-05T20:53:53.53125</pubDate>
<guid>ff7bbf19-9155-4773-913c-767bcbf09904</guid>
</item>
<item>
<title>Second article title</title>
<description>Second Article Description</description>
<pubDate>2006-12-05T20:53:53.5625</pubDate>
<guid>8a3fd5e8-b99f-49fe-8a43-7fb62d80c18c</guid>
</item>
</channel>
</rss>

Create XML doc by LINQ, add xmlns,xmlns:xsi to it

I try to create an GPX XML document by LINQ to XML.
Everything works great, except adding xmlns, xmlns:xsi attributes to the doc. By trying it different way I get different exceptions.
My code:
XDocument xDoc = new XDocument(
new XDeclaration("1.0", "UTF-8", "no"),
new XElement("gpx",
new XAttribute("creator", "XML tester"),
new XAttribute("version","1.1"),
new XElement("wpt",
new XAttribute("lat","7.0"),
new XAttribute("lon","19.0"),
new XElement("name","test"),
new XElement("sym","Car"))
));
The output should also contain this:
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
How can I add it by Linq to XML? I tried several ways but it does not work, exceptions during compile time.
See How to: Control Namespace Prefixes. You could use code like this:
XNamespace ns = "http://www.topografix.com/GPX/1/1";
XNamespace xsiNs = "http://www.w3.org/2001/XMLSchema-instance";
XDocument xDoc = new XDocument(
new XDeclaration("1.0", "UTF-8", "no"),
new XElement(ns + "gpx",
new XAttribute(XNamespace.Xmlns + "xsi", xsiNs),
new XAttribute(xsiNs + "schemaLocation",
"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"),
new XAttribute("creator", "XML tester"),
new XAttribute("version","1.1"),
new XElement(ns + "wpt",
new XAttribute("lat","7.0"),
new XAttribute("lon","19.0"),
new XElement(ns + "name","test"),
new XElement(ns + "sym","Car"))
));
You have to specify the namespace for each element, because that's what using xmlns this way means.
From http://www.falconwebtech.com/post/2010/06/03/Adding-schemaLocation-attribute-to-XElement-in-LINQ-to-XML.aspx:
To generate the following root node and namespaces:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.foo.bar someSchema.xsd"
xmlns="http://www.foo.bar" >
</root>
Use the following code:
XNamespace xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
XNamespace defaultNamespace = XNamespace.Get("http://www.foo.bar");
XElement doc = new XElement(
new XElement(defaultNamespace + "root",
new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
new XAttribute(xsi + "schemaLocation", "http://www.foo.bar someSchema.xsd")
)
);
Be aware - if you want to add elements to the document, you need to specify the defaultNamespace in the element name or you will get xmlns="" added to your element. For example, to add a child element "count" to the above document, use:
xdoc.Add(new XElement(defaultNamespace + "count", 0)

How do I add multiple Namespace declarations to an XDocument?

I'm using an XDocument to build an Xml document in a known structure. The structure I am trying to build is as follows:
<request xmlns:ns4="http://www.example.com/a" xmlns:ns3="http://www.example.com/b" xmlns:ns2="http://www.example.com/c" >
<requestId>d78d4056-a831-4c7d-a357-d14402f623fc</requestId>
....
</request>
Notice the "xmlns:nsX" attributes.
I am trying, without success, to add these attributes to my "request" element.
XNamespace ns4 = XNamespace.Get("http://www.example.com/a");
XNamespace ns3 = XNamespace.Get("http://www.example.com/b");
XNamespace ns2 = XNamespace.Get("http://www.example.com/c");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "no"),
new XElement("request",
new XAttribute("ns4", ns4),
new XAttribute("ns3", ns3),
new XAttribute("ns2", ns2),
new XElement("requestId", Guid.NewGuid())
)
);
However, this produces the following:
<request ns4="http://www.example.com/a" ns3="http://www.example.com/b" ns2="http://www.example.com/c">
<requestId>38b07cfb-5e41-4d9a-97c8-4740c0432f11</requestId>
</request>
How do I add the namespace declarations correctly?
Do you mean:
new XAttribute(XNamespace.Xmlns + "ns4", ns4),
new XAttribute(XNamespace.Xmlns + "ns3", ns3),
new XAttribute(XNamespace.Xmlns + "ns2", ns2),

Categories

Resources