using CsQuery;
namespace CSQuery
{
class Program
{
static void Main(string[] args)
{
var dom = CQ.Create(/*I am not sure what goes here*/);
//Not sure if this is the correct setup as well
CQ mf = dom["MANUFACTURER"];
CQ md = dom["MODEL"];
Console.WriteLine(mf);
Console.WriteLine(md);
Console.ReadKey();
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
--------------------------------------------------------
PARTS:
Title: Computer Parts
<ITEM>Motherboard</ITEM>
<MANUFACTURER>ASUS</MANUFACTURER>
<MODEL>P3B-F</MODEL>
<COST> 123.00</COST>
<ITEM>Video Card</ITEM>
<MANUFACTURER>ATI</MANUFACTURER>
<MODEL>All-in-Wonder Pro</MODEL>
<COST>160.00</COST>
<ITEM> Monitor </ITEM>
<MANUFACTURER>LG Electronics</MANUFACTURER>
<MODEL> 995E</MODEL>
<COST> 290.00</COST>
</PART></PARTS>
Above is my code I have written so far I am trying to extract the MANUFACTURER and MODEL from the sample given xml code. When I compile I get an error message saying source can not be found and I think it may be a problem with my setup and I am unclear on what exactly is suppose to go into my CQ.Create() as a parameter(I tried putting in the exact parts.xml file but that didn't help).
Related
I have 2 xml files:
File 1
<xml version.....>
<System>
<General>
<Instrument>
<Specific>
<Name>...</Name>
</Specific>
<Instrument>
</General>
<System>
File 2
<System>
<Specific>
<Name>...</Name>
<age>...</age>
....
</Specific>
<System>
File 1 only has one entry under the element Specific, File 2 has multiple entries under the element specific. I need to replace all the entries under Specific in File 1 with the entries under Specific in File 2.
How is this be done in c#, using System.Xml.Linq or System.Xml???
Good day.
You can do that iteratively adding nodes from one element to another like this using LinqToXml.
using System.Xml.Linq;
namespace XmlReplacer
{
class Program
{
static void Main(string[] args)
{
var doc1 = XDocument.Load(#"d:\temp\file1.xml");
var doc2 = XDocument.Load(#"d:\temp\file2.xml");
var specElement1 = doc1.Root.Element("General").Element("Instrument").Element("Specific");
var specElement2 = doc2.Root.Element("Specific");
specElement1.RemoveAll();
foreach (var xElement in specElement2.Elements())
{
specElement1.Add(xElement);
}
doc1.Save(#"d:\temp\file3.xml");
}
}
}
Result is file3.xml:
<?xml version="1.0" encoding="utf-8"?>
<System>
<General>
<Instrument>
<Specific>
<Name>Test2</Name>
<Age>10</Age>
</Specific>
</Instrument>
</General>
</System>
I've been trying to read an xml file from an external source to get it into a dataset. I've taken the schema and compiled my class through xsd and have loaded it into the solution.
my xml:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<CAMDealerManifest AssetURL="http://www.the placewherethefilelives.com/CAMPublic/d98c8185/" DealerCode="41065" DealerGuid="bc0d0bc8-b37b-11e3-a345-ac162dbc18f8" DealerName="Ron Hibbard Toyota" ManifestId="13" ManifestURL="http://www.toyota.com/CAMPublic/d/41065-bc0d0bc8.xml" Path="41065-bc0d0bc8" ProviderId="1011" WebsiteVendorName="WorldDealer">
<CAMCampaigns count="15" dateTime="2014-09-16T17:18:40.877-07:00">
<CAMCampaign ManifestId="13" endDate="2014-12-31T11:59:59-08:00" flightDates="08/01/14 - 12/31/14" geography="National" groupName="National" id="68" name="National - Corolla Style Elevated" priority="0" required="false" startDate="2014-08-01T12:00:00-07:00">
<CAMCreative SubGroup="Corolla Style Elevated" Id="49" Name="National - Corolla Style Elevated" ImageAltText="Toyota's national banner for the stylish 2014 Corolla" ImageSearchTerms="Toyota, 2014 Corolla, Style Elevated, New Heights" Link="New Inventory" Model="Corolla" MonthYear="08-2014" Priority="3" Required="false">
<CAMCreativeSource CAMAssetCount="1" Height="409" Width="990" MediaBinAssetId="0E1C886A-C5CE-4409-AD36-7070D614A7A6" MediaBinFileName="03-14_01_2014_nat-style-elevated_990x409_0000000460_corolla_o_xta.jpg">
<CAMAsset Path="National/Corolla-Style-Elevated/National---Corolla-Style-Elevated/990/409/" Id="1273" Name="08-14_01_National-Corolla-Style-Elevated_990x409_431_Corolla_O_xta.jpg" Height="409" Width="990" assetType="JPG" Guid="b9f4d3cd-fefd-4ff3-b209-338f409e551c" Md5Hex="3e328dc32a2db9fc1f3d6a2167d3e5d2">
<CAMTracking>
<SiteCatalyst version="1.0">
<Click tmsomni.events="event28" tmsomni.products=";08-14_01_National-Corolla-Style-Elevated_990x409_431_Corolla_O_xta;;;event28=1"/>
<Impression tmsomni.events="event29" tmsomni.products=";08-14_01_National-Corolla-Style-Elevated_990x409_431_Corolla_O_xta;;event29=1;evar43=img|evar61=corolla|evar54=o|evar49={$CAM_PAGE_POSITION}"/>
</SiteCatalyst>
</CAMTracking>
</CAMAsset>
</CAMCreativeSource>
</CAMCreative>
</CAMCampaign>
</CAMCampaigns>
<CAMExpiredCampaigns count="0" dateTime="2014-09-16T17:18:40.873-07:00"/>
</CAMDealerManifest>
I can't seem to get this xml to list or put into a dataset. I'm new to deserializing xml and could use some assistance.
Simply call ReadXml with the path to the file:
var dataSet = new DataSet();
dataSet.ReadXml(string PathToFile);
Works pretty well; will even create all the relations (notice CAMDealerManifestId in the screenshot).
Your file went in with only a modification to the XML declaration -- had to change standalone value from true to yes:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
If you're reading this in as a string, you could do something like this:
var xmlString = HoweverYouGetTheString().Split(new string[] { "\r\n" }, StringSplitOptions.None);
xmlString[0] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
using (var reader = new System.IO.StringReader(String.Join("\r\n", xmlString)))
{
dataSet.ReadXml(reader);
}
I have this problem with my C# API that I unfortunately posted incorrectly & got partially incorrect answers, so I'm going to try again since I've still not solved it (trying for hours)
Here's my XML file :
<CHandlingDataMgr>
<HandlingData>
<Item type="CHandlingData">
<handlingName>Plane</handlingName>
<fMass value="140000.000000" />
<SubHandlingData>
<Item type="CFlyingHandlingData">
<handlingType>HANDLING_TYPE_FLYING</handlingType>
<fThrust value="0.630000" />
</SubHandlingData>
</Item>
</Item>
Please note: SubHandlingData is in a separate sub-section within the same item, a 2nd item type is called.
Here's the C# Code :
private void button2_Click(object sender, EventArgs e)
{
var items = doc.Descendants("HandlingData").Elements("Item");
var query = from i in items
select new
{
HandlingName = (string)i.Element("handlingName"), (decimal?)i.Element("fThrust").Attribute("value"),
HandlingType = (string)i.Element("handlingType")
};
StringBuilder test = new StringBuilder();
foreach (var item in query)
{
var k = item.dunno;
test.Append(k);
richTextBox1.Text = test.ToString();
}
}
The above code works fine, but doesn't work with SubHandlingData. This means such values as HandlingType is not seen, I've added the element for this & it returns errors, have also tried including multiple decedents which then doesn't find HandlingName, or HandlingType. I want my output to be if handlingType == "HANDLING_TYPE_FLYING", richtextbox1.text = this.HandlingName. I hope I have explained this clearly enough to gain an answer as this has troubled me for a while.
My Problem in short: Program does not find any SubHandlingData inside my XML document.
Question in short: How to find <SubHandlingData> inside <item> (how to find sub-section of code inside same item)
From #Matthew's edit, you can see there is <Item> not closed within <SubHandlingData>. If your actual XML has such structure then it won't get parsed successfully to XDocument. But if your actual XML has it closed, about like so I assume :
<HandlingData>
<Item type="CHandlingData">
<handlingName>Plane</handlingName>
<fMass value="140000.000000" />
<SubHandlingData>
<Item type="CFlyingHandlingData">
<handlingType>HANDLING_TYPE_FLYING</handlingType>
<fThrust value="0.630000" />
</Item>
</SubHandlingData>
</Item>
</HandlingData>
... then we can continue. You can try to follow path from outer Item to handlingType which is : SubHandlingData > Item > handlingType, to get handlingType data from current outer item :
var query = from i in items
select new
{
HandlingName = (string)i.Element("handlingName"),
HandlingType = (string)i.Element("SubHandlingData")
.Element("Item")
.Element("handlingType")
};
I have the following code which seems to throw a "Invalid cross-thread access." and I can't seem to figure out why. I'm loading a remote xml file from a URL, however, when parsing that XML I always receive this error. Any suggestions?
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
string xml = streamReader.ReadToEnd();
using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
{
reader.ReadToFollowing("channel");
reader.MoveToFirstAttribute();
reader.ReadToFollowing("title");
output.AppendLine("Title: " + reader.ReadElementContentAsString());
reader.ReadToFollowing("description");
output.AppendLine("Desc: " + reader.ReadElementContentAsString());
textBox1.Text = output.ToString(); //Invalid cross-thread access.
}
}
The XML I'm trying to parse looks like the following, I'm just trying to parse bits and pieces as I continue to learn how to use c# to parse different types of XML:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"xmlns:dc="http://purl.org /dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0 /modules/slash/">
<channel>
<title>Server & Site News</title>
<description>A place for the Admin and Moderators to post the latest news on both the server and site.</description>
<pubDate>Fri, 18 May 2012 22:45:08 +0000</pubDate>
<lastBuildDate>Fri, 18 May 2012 22:45:08 +0000</lastBuildDate>
<generator>Forums</generator>
<link>http://removedurl.com/forums/server-site-news.23/</link>
<atom:link rel="self" type="application/rss+xml" href="http://removedurl.com/forums/server-site-news.23/index.rss"/>
<item>
<title>Example Title</title>
<pubDate>Mon, 14 May 2012 17:39:45 +0000</pubDate>
<link>http://removedurl.com/threads/back-fully-working.11013/</link>
<guid>http://removedurl.com/threadsback-fully-working.11013/</guid>
<author>Admin</author>
<dc:creator>Admin</dc:creator>
<slash:comments>14</slash:comments>
</item>
</channel>
textBox1.Text = output.ToString(); //Invalid cross-thread access.
you get that because you are calling UI thread while you are doing operations on IO thread. Try separating those operations or call invoke on the UI thread.
try changing your code to something like this.
Dispatcher.BeginInvoke( () => { //your ui update code } );
To add a bit more detail from Mayank:
Dispatcher.BeginInvoke( () => {
textBox1.Text = output.ToString()
} );
You have to marshal the call to UI objects back to the UI thread. Nothing can modify UI elements on any other thread than the main one.
I am writing a class library which abstracts data contained in XML files on a web site. Each XML file uses the same root element: page. The descendant(s) of page depend on the specific file that I am downloading. For example:
<!-- http://.../groups.xml -->
<page url="/groups.xml">
<groups>
<group id="1" >
<members>
<member name="Adrian" />
<member name="Sophie" />
<member name="Roger" />
</members>
</group>
</groups>
</page>
<!-- http://.../project.xml?n=World%20Domination -->
<page url="/project.xml">
<projectInfo>
<summary classified="true" deadline="soon" />
<team>
<member name="Pat" />
<member name="George" />
</team>
</projectInfo>
</page>
There are also several additional XML files that I would like to download and process, eventually. For that reason, I have been trying to come up with a nice, clean way to deserialize the data. I've tried a few approaches, but each approach leaves me feeling a little dirty when I look back over my code. My latest incarnation utilizes the following method:
internal class Provider
{
/// <summary>Download information from the host.</summary>
/// <typeparam name="T">The type of data being downloaded.</typeparam>
internal T Download<T>(string url) where T : IXmlSerializable, new()
{
try
{
var request = (HttpWebRequest)WebRequest.Create(url);
var response = (HttpWebResponse)request.GetResponse();
using (var reader = XmlReader.Create(response.GetResponseStream()))
{
// Skip the XML prolog (declaration and stylesheet reference).
reader.MoveToContent();
// Skip the `page` element.
if (reader.LocalName == "page") reader.ReadStartElement();
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(reader);
}
}
catch (WebException ex) { /* The tubes are clogged. */ }
}
}
[XmlRoot(TypeName = "groups")]
public class GroupList : List<Group>, IXmlSerializable
{
private List<Group> _list;
public void ReadXml(XmlReader reader)
{
if (_list == null) _list = new List<Group>();
reader.ReadToDescendant("group");
do
{
var id = (int)reader["id"];
var group = new Group(id);
if (reader.ReadToDescendant("member"))
{
do
{
var member = new Member(reader["name"], group);
group.Add(member);
} while (reader.ReadToNextSibling("member"));
}
_list.Add(group);
} while (reader.ReadToNextSibling("group"));
reader.Read();
}
}
This works, but I feel like there is a better way that I'm not seeing. I tried using the xsd.exe utility when I started this project. While it would minimize the amount of code for me to write, it did not feel like the ideal solution. It would be the same approach that I'm using now -- I would just get there faster. I'm looking for a better solution. All pages have the page element in common -- isn't there a way to take advantage of that? Would it be possible to have a serializable container class Page that could contain a combination of other objects depending on the file downloaded? Are there any simpler ways to accomplish this?
.NET provides a "xsd.exe" utility on the command line.
Run xsd.exe (xmlfilename) on your original xml file and it'll derive a XML schema (xsd) from your XML data file.
Run xsd.exe (xsd file name) /C and it'll create a C# class which can be used to deserialize such an XML file into a C# class.
Of course, since it only has a single XML file to go on, xsd.exe isn't perfect in its XML schema it derives - but that could be quick'n'easy starting point for you to get started.