I have a XML world map which basically takes two inputs (its a XML file with corresponding CSS files and stuff): the country input and country address. So when I manually enter the data into the XML file (Country name and country address) the country on the map changes its color and on hovering over that country I can see what I've entered.
I have a list of all countries in my DB. So I was thinking of there is any way for me to write in all those countries from my DB into the XML file. I was thinking of something like this:
for(int i=0; i<list.count;i++)
{
list[i].CounryName = //write it into the XML file;
list[i].CountryUserAddress = //Write it into the XML file;
}
So the idea is to when the for loop goes on and on, every country is written in into the XML file. I don't have any significant experience working with XML files in ASP.NET and I'm stuck on dry land here. All this should be done via code behind. Can someone help me out with this, or at least point me into the right direction?
Thanks heaps!
P.S. I've forgot to mention that I should be actually overwriting the already existing XML file, not creating a new one...
Here's an example of how you could do this with the data you provided:
public string EditDoc()
{
string filename = "Path/MyFileName.xml";
List<string> list = new List<string>();
if (File.Exists(filename)) //we have the file, so update it
{
XmlDocument myDoc = new XmlDocument(); //create a document object
myDoc.Load(filename); //load existing info
XmlNode root = myDoc.DocumentElement; //the root node ("Country")
XmlNode nodeToUpdate = root.SelectSingleNode("CountryName"); //select the node to update
nodeToUpdate.Value = "new info"; //give it a new value
myDoc.Save(filename); //save the document
}
else //didn't find the file
{
XmlDocument myDoc = new XmlDocument(); //create a new document
XmlNode countryList = myDoc.CreateElement("CountryList");
myDoc.AppendChild(countryList);
for (int i = 0; i < list.Count; i++)
{
XmlNode country = myDoc.CreateElement("Country"); //create the parent "Country" element
myDoc.AppendChild(countryList); //append to the list
XmlNode countryName = myDoc.CreateElement("CountryName"); //create element for "CountryName"
countryName.AppendChild(myDoc.CreateTextNode(list[i].CountryName)); //add data from list index
country.AppendChild(countryName); //append this as a child to "Country"
XmlNode countryUserAddress = myDoc.CreateElement("CountryUserAddress"); //create element for "CountryUserAddress"
countryUserAddress.AppendChild(myDoc.CreateTextNode(list[i].CountryUserAddress)); //add data from list index
country.AppendChild(countryUserAddress); //append as a child to "Country"
}
myDoc.Save(filename); //save the document
}
}
The general idea is to traverse the document's tree and select that value to update. There may be a better way to do this, but this is the way I'm familiar with. Similarly, you can create an xml document in the same manner.
The subject matter is different, but this helped me tremendously in understanding reading/writing XML data: this link
EDIT: I updated the code slightly to make the parent element "CountryList" and append each "Country" in the DB to that. The document will end up coming out something like:
<CountryList>
<Country>
<CountryName>Blah</CountryName>
<CountryUserAddress>Blah</CountryUserAddress>
</Country>
<Country>
<CountryName>Blah</CountryName>
<CountryUserAddress>Blah</CountryUserAddress>
</Country>
</CountryList>
Related
I would like to Read and Deserialize more than one XML file into my XML class structure given a list of strings consisting of file names.
Obviously when reading ONE xml file, you can go like this:
XmlRoot file = null;
XmlSerializer ser = new XmlSerializer(typeof(XmlRoot));
using (XmlReader read = XmlReader.Create(FileName))
{
file = (XmlRoot)ser.Deserialize(read);
{
Which will deserialize the XML file into the class structure?
It is not possible to have a list with file names and use a foreach loop to iterate over them, reading and deserializing one by one as it would theoretically result into multiple root elements being read, deserialized and replicated in the class structure.
So in general I would like to deserialize each file and append the required master elements to a root object.
Does anyone know how to accomplish this? It would be of great help.
Thanks in advance!
PS: Excuse me for my English, as I am not a native speaker. If you need further information, just tell me!
I managed to solve the problem for myself.
First i created a XDocument for the first file i read, afterwards i iterate through the other documents creating a new XDocument for every xml file and try to get the elements after the root (Language in my case) and add it to the root of the XDocument created outside the loop.
XDocument lDoc = new XDocument();
int counter = 0;
foreach (var fileName in multipleFileNames)
{
try
{
counter++;
if (lCounter <= 1)
{
doc = XDocument.Load(fileName);
}
else
{
XDocument doc2 = XDocument.Load(fileName);
IEnumerable<XElement> elements = doc2.Element("Language")
.Elements();
doc.Root.Add(elements);
}
}
return Deserialize(lDoc);
Afterwards i call the Deserialize method, deserializing my created XDocument like this:
public static XmlLanguage Deserialize(XDocument doc)
{
XmlSerializer ser = new XmlSerializer(typeof(XmlLanguage));
return (XmlLanguage)ser.Deserialize(doc.CreateReader());
}
I'm delving into the world of XmlDocument building and thought I'd try to re-build (at least, in part) the Desktop tree given by Microsoft's program UISpy.
So far I am able to grab a child of the desktop and write that to a XML document, and then grab each child of that and write those to an XML document.
So far the code looks like this...
using System.Windows.Automation;
using System.Xml;
namespace MyTestApplication
{
internal class TestXmlStuff
{
public static void Main(string[] args)
{
XmlDocument xDocument = new XmlDocument();
AutomationElement rootElement = AutomationElement.RootElement;
TreeWalker treeWalker = TreeWalker.ContentViewWalker;
XmlNode rootXmlElement = xDocument.AppendChild(xDocument.CreateElement("Desktop"));
AutomationElement autoElement = rootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "GitHub"));
string name = autoElement.Current.Name;
while (autoElement != null)
{
string lct = autoElement.Current.LocalizedControlType.Replace(" ", "");
lct = (lct.Equals("") ? "Cusotm" : lct);
XmlElement temp = (XmlElement)rootXmlElement.AppendChild(xDocument.CreateElement(lct));
//temp.InnerText = lct;
string outerXML = temp.OuterXml;
rootXmlElement = temp;
autoElement = treeWalker.GetNextSibling(autoElement);
}
}
}
}
...and the resulting XML file...
Now, when I add a line to change the InnerText Property of each XML element, like temp.InnerText = lct I get an oddly formated XML file.
What I expected from this was that each InnerText would be on the same line as the start and end tags of the XML element, but instead all but the last element's InnerText is located on a new line.
So my question is, why is that? Is there something else I could be doing with my XML elements to have their InnerText appear on the same line?
As I said in a comment, XML isn't a display format, so it gets formatted however IE chooses to do so.
To get closer to what you were expecting, you might want to consider using an attribute rather than innertext:
XmlElement temp = (XmlElement)rootXmlElement.AppendChild(xDocument.CreateElement(lct));
var attr = xDocument.CreateAttribute("type");
attr.Value = lct;
temp.Attributes.Append(attr);
IE displays the attributes within the opening element, which may be good enough for your purposes.
From the XML perspective, what you're currently creating is called Mixed Content - you have an element that contains both text and other elements. From a hierarchical perspective, those text nodes and other elements occupy the same position within the hierarchy - so I'd assume that this is why IE is displaying them as "equals" - both nested under their parent element and at the same indentation level.
I have an XML file which contain images, The images are of the form [[ID]] where ID is the unique identifier for an image stored in the database. I want to parse this XML file for [[ ]] tags and replace the tags with the images which will be fetched from the database. Upto this point, this is what I have done
string xmlUrl = Server.MapPath("/Model Report.xsl");
XmlDocument doc = new XmlDocument();
doc.Load(xmlUrl);
now want to parse doc for [[ ]] tags. The image in the XML file looks like this(this is only a part of XML file.)
<table-graphics.as-jpeg datatype="string" display-name="As JPEG">[[ID]]</table-graphics.as-jpeg>
Your help is truly appreciated.
It's still not clear to me what you are asking. Sounds like you are trying to treat the XML document like a plain text document; in which case:
string xmlUrl = Server.MapPath("/Model Report.xsl");
string raw = new WebClient().DownloadString(xmlUrl);
var output = new List<string>();
int left = 0;
int right = 0;
while ((left = raw.IndexOf("[[", right)) >= 0) {
int right = raw.IndexOf("]]", left);
if (right > left) output.Add(raw.Substring(left+2, right-left-2));
}
should give all the [[something]] patterns in the document.
If you know more about the document, like all the IDs will be in table-graphics.as-jpeg tags, you should use the XPath support as Mark said:
string xmlUrl = Server.MapPath("/Model Report.xsl");
XmlDocument doc = new XmlDocument();
doc.Load(xmlUrl);
foreach (XmlNode node in doc.SelectNodes("//table-graphics.as-jpeg"))
{
node.InnerText . . .
}
Take a look at the XPath support in C# to help with the parsing.
[...edit...]
You'll want to look for the table-graphics.as-jpeg elements, then grab their text content. (Don't have the exact syntax in my head -- I always have to look it up myself.)
So I'm working on a speech recognition program in C# and while trying to implement the YAHOO News API into the program I am getting no response.
I won't copy/paste my whole code as it would be very long so here are the main bits.
private void GetNews()
{
string query = String.Format("http://news.yahoo.com/rss/");
XmlDocument wData = new XmlDocument();
wData.Load(query);
XmlNamespaceManager manager = new XmlNamespaceManager(wData.NameTable);
manager.AddNamespace("media", "http://search.yahoo.com/mrss/");
XmlNode channel = wData.SelectSingleNode("rss").SelectSingleNode("channel");
XmlNodeList nodes = wData.SelectNodes("rss/channel/item/description", manager);
FirstStory = channel.SelectSingleNode("item").SelectSingleNode("title", manager).Attributes["alt"].Value;
}
I believe I have done something wrong here:
XmlNode channel = wData.SelectSingleNode("rss").SelectSingleNode("channel");
XmlNodeList nodes = wData.SelectNodes("rss/channel/item/description", manager);
FirstStory = channel.SelectSingleNode("item").SelectSingleNode("title", manager).Attributes["alt"].Value;
Here is the full XML Document: http://news.yahoo.com/rss/
If any more info is required let me know.
Hmm I have implemented my own code to get news from Yahoo, I read all the news Title ( which is located at rss/channel/item/title ) and Short story ( which is located rss/channel/item/description ).
The short story is the problem for news, and that is the point when we need to get all the inner text of description node in a string and then parse it like XML. The text code is in this format and the Short story is right behind </p>
<p><a><img /></a></p>"Short Story"<br clear="all"/>
We need to modify it since we have many xml roots (p and br) and we add an extra root <me>
string ShStory=null;
string Title = null;
//Creating a XML Document
XmlDocument doc = new XmlDocument();
//Loading rss on it
doc.Load("http://news.yahoo.com/rss/");
//Looping every item in the XML
foreach (XmlNode node in doc.SelectNodes("rss/channel/item"))
{
//Reading Title which is simple
Title = node.SelectSingleNode("title").InnerText;
//Putting all description text in string ndd
string ndd = node.SelectSingleNode("description").InnerText;
XmlDocument xm = new XmlDocument();
//Loading modified string as XML in xm with the root <me>
xm.LoadXml("<me>"+ndd+"</me>");
//Selecting node <p> which has the text
XmlNode nodds = xm.SelectSingleNode("/me/p");
//Putting inner text in the string ShStory
ShStory= nodds.InnerText;
//Showing the message box with the loaded data
MessageBox.Show(Title+ " "+ShStory);
}
Choose the me as the right answer or vote me up if the code works for you. If there are any issues you can ask me. Cheers
It's likely that you are passing that namespace manager to those attributes, but I'm not 100% certain. Those are definitely not in that .../mrss/ namespace, so I would guess that is your problem.
I would try it without passing the namespace (if possible) or using the GetElementsByTagName method to avoid namespace issues.
Tag contains the text rather than Xml.
Here is an example to display text news:
foreach (XmlElement node in nodes)
{
Console.WriteLine(Regex.Match(node.InnerXml,
"(?<=(/a>)).+(?=(</p))"));
Console.WriteLine();
}
I want to retrieve the XML data from db and bound it to the DropDownList.
XML data in the db field is follows:
<Root>
<ClientName>Jim</ClientName>
<ClientName>John</ClientName>
<ClientName>Andrew</ClientName>
</Root>
i retrieved the xml data from db field. but, i got next error:
Data at the root level is invalid. Line 1, position 1
The following code used to retrieve the xml data from db field. do you have any idea about this problem?
var list = from drp in zephyrEntities.UserDefinedFields
where drp.UDF_ID == udfid
select drp.LIST_VALUES; // xml field in the db
XmlDocument doc = new XmlDocument();
XElement xelement = new XElement("UserDefinedList", list);
string str = String.Concat(xelement.Nodes());
doc.LoadXML(str);
XmlNodeList childNodes = doc.GetElementsByTagName("ClientName");
if (childNodes != null)
{
for (int i = 0; i < childNodes.Count; i++)
{
XmlNode valueNode = childNodes[i].SelectSingleNode("text()");
}
}
It is not clear why you store list of entities as one value. Try to normalize your DB model.