c# xml look for node with / in title - c#

I've got a WFA running which takes an XML file and "prettifys" it.
what I would like to add now is a check to see if a specific node exists, and if not , display a message.
the XML looks like
<message>
<success/>
<bookings>
Some extra nodes I need not look for at this time
</bookings>
</message>
what I am (unsuccessfully) trying to do it to look for the existence of
<success/>
and if not found, display a message.
The code I have be trying to do this with is
InitializeComponent();
openFileDialog1.FileName = String.Empty; //blank filename
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
richTextBox1.LoadFile(openFileDialog1.FileName, RichTextBoxStreamType.PlainText);
XmlDocument doc = new XmlDocument();
doc.Load(openFileDialog1.FileName);
XmlNodeList nodeToFind = doc.GetElementsByTagName("success/");
if (nodeToFind != null)
{
richTextBox2.AppendText("node found");
}
this did not work, so I tried it by doing a .Count on nodeToFind, and loading the value into a VAR (called Successful) and then amending the If to
if (Successful !=0) {
display a message
}
but that only comes back with 0 each time.
I am guessing that the it might be the / in the node name.
can anyone help ?
thanks
EDIT:
WORKING CODE now looks like
InitializeComponent();
openFileDialog1.FileName = String.Empty; //blank filename
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
richTextBox1.LoadFile(openFileDialog1.FileName, RichTextBoxStreamType.PlainText);
XmlDocument doc = new XmlDocument();
doc.Load(openFileDialog1.FileName);
XmlNodeList nodeToFind = doc.GetElementsByTagName("success");
int Successfull = nodeToFind.Count;
if (Successfull == 0)
{
richTextBox2.AppendText("node NOT found");
}
}
thanks #SLaks

That's a self-closing tag (equivalent to <success></success>).
The / is not part of the name.

Related

How to use Linq to XML to override existing XML file

I have a simple XML file structured like this
<?xml version="1.0" encoding="utf-8" ?>
<event>
<name>Test Event</name>
<date>06/09/1990</date>
<description>Birthday</description>
<blogURL></blogURL>
</event>
What I am trying to achieve is to have a form accept user input to create a new XML document with the same structure that will overwrite the old one.
The XML document is in the same directory as the ASPX page that will accept the input.
When the user navigates to the PressRelease.aspx page, it loads the values in the document.
var doc = XDocument.Load(Server.MapPath("~/PressSection.xml"));
string currentEventName = (string)doc.Descendants("name").Single();
string currentEventDate = (string)doc.Descendants("date").Single();
string currentEventDescription = (string)doc.Descendants("description").Single();
string currentEventLink = (string)doc.Descendants("blogURL").Single();
if (currentEventLink.ToString() == "")
{
CurrentEventURL.Text = "This event has no URL";
}
CurrentEventName.Text = currentEventName;
CurrentEventDescription.Text = currentEventDescription;
CurrentEventDate.Text = currentEventDate;
This works. I am grabbing the user input and doing simple validation like this
string newEventName = NewEventName.Text;
string newEventDescription = NewDescription.Text;
string newEventDate = NewDate.SelectedDate.Value.Date.ToString();
string newEventURL = NewURL.Text;
if (newEventName == "")
{
MessageBox.Text = "Please enter a valid event name";
MessageBox.CssClass = "event_error";
return;
}
if (newEventDescription == "")
{
MessageBox.Text = "Please enter a valid description";
MessageBox.CssClass = "event_error";
return;
}
if (newEventDate == null)
{
MessageBox.Text = "Please select a valid date";
MessageBox.CssClass = "event_error";
return;
}
And finally, I build and save the new XML document like this
//Create new document
XDocument newEventDocument = new XDocument(new XDeclaration("1.0", "utf-8", null));
//Addd root node
XElement RootNode = new XElement("Event");
//add root node to new document
newEventDocument.Add(RootNode);
//Add event name element then add it to the new document
XElement eName;
eName = new XElement("name");
eName.Value = newEventName;
newEventDocument.Root.Add(eName);
//Add event date element then add it to the new document
XElement eDate;
eDate = new XElement("date");
eDate.Value = newEventDate;
newEventDocument.Root.Add(eDate);
//Add event description element then add it to the new document
XElement eDescription;
eDescription = new XElement("description");
eDescription.Value = newEventDescription;
newEventDocument.Root.Add(eDescription);
//Add event URL element then add it to the new document
XElement eURL;
eURL = new XElement("blogURL");
eURL.Value = newEventURL;
newEventDocument.Root.Add(eURL);
//Finally, save the document
newEventDocument.Save("PressSection.xml", SaveOptions.None);
The issue that my program throws is an invalid permissions problem.
Access to the path 'C:\Program Files (x86)\IIS Express\PressSection.xml' is denied.
My question is, how do I save this in the root of my project directory, instead of IN MY IIS Express folder? I need it to overwrite the existing 'PressSection.xml' file that already exists in my project. Thanks!
This worked for it. Sorry for such an easy question
string path = Server.MapPath("PressSection.xml");
newEventDocument.Save(Path.Combine(path));

XDocument and load too large XML file on demand [duplicate]

This question already has answers here:
XDocument Get Part of XML File
(3 answers)
Closed 8 years ago.
I did write this code to read a url of xml file:
XDocument feedXml = XDocument.Load("url address of xml file here");
var feeds = from feed in feedXml.Descendants("List")
select new Event {
Id = Int32.Parse(feed.Element("ID").Value),
Name = feed.Element("Name").Value,
City = feed.Element("City").Value
};
return feeds;
My problem is that the file is too large (about 40MB) and take too much time to load.
So I am using XmlReader to read xml file but this was not applicable too because I don't know how to load every (for example 10) records in every page on demand and I should read the whole file every time and skip other records to reach appropriate elements, shouldn't I?
string XmlFileUrl = #"url address of xml file here";
using (XmlReader reader = new XmlTextReader(XmlFileUrl))
{
bool openItem = false;
Event item = new Event();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "List")
{
item = new Event();
openItem = true;
}
else if (reader.Name == "Name" && openItem)
item.Name = reader.ReadElementContentAsString();
...
}
else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "List" && openItem)
{
openItem = false;
feeds.Add(item);
}
}
}
Is there any way to use Jquery ajax or convert the xml file to json with paging to load just needed data on every page, or any suggestion?
I think this is not so easy to achieve with a XML structure and maybe in this case is XDocument.Load not the appropriate method, because AFAIK it always loads the whole document immediately. You can try the overload with the Stream parameter, instead of URL, and try loading only a part of the the file over the net. Probably you need to write your own loader (that gets only a portion of the file, maybe XmlDocument?) and parse the incomplete structure by yourself.
If you can call portions of the XML file controlled by the URI (for example: http://domain/entries?page=10&take=20 and this call returns a valid XML), then an option would be to use this URL instead of the link to the whole file, something like:
var pagedUri = #"http://domain/entries?page=10&take=20";
XDocument feedXml = XDocument.Load(pagedUri);
var feeds = from feed in feedXml.Descendants("List")
select new Event {
Id = Int32.Parse(feed.Element("ID").Value),
Name = feed.Element("Name").Value,
City = feed.Element("City").Value
};
return feeds;
Have a look at this SO post where a similar problem is addressed.

How to check if xml file is empty or not using c#

Hello everyone I want to check my xml file if it is empty or not. I am trying to update one xml data to another for this I am using the following code.Now Please tell me how can I check if my xml file has data or not
Here is the code I am using for update my xml file
protected void CheckUpdates()
{
StringReader strReader = new StringReader("..\\xml\\Updatelist.xml");
XmlReader reader = XmlReader.Create(strReader);
try
{
while (reader.Read())
{
var originalXmlDoc = XDocument.Load("..\\xml\\list.xml"); var newXmlDoc = XDocument.Load("..\\xml\\Updatelist.xml");
foreach (var newElement in newXmlDoc.Element("blocker").Elements("lst"))
{
newElement.Value.Trim();
if (!originalXmlDoc.Element("blocker").Elements("lst")
.Any(oldElement => oldElement.Value.Trim().Equals(
newElement.Value.Trim(),
StringComparison.InvariantCultureIgnoreCase)))
{
originalXmlDoc.Element("blocker").Add(new XElement("lst", newElement.Value));
}
}
originalXmlDoc.Save("..\\xml\\list.xml", SaveOptions.None);
XmlDocument doc = new XmlDocument();
doc.Load("..\\xml\\Updatelist.xml");
doc.DocumentElement.RemoveAll();
doc.Save("..\\xml\\Updatelist.xml");
}
}
catch (XmlException ex)
{
//Catch xml exception
//in your case: root element is missing
}
}
I am Getting this error
Data at the root level is invalid. Line 1, position 1.
Please tell me how can I check if my Updatelist.xml is empty or not?
Now I get this error
Two ways to do it.
The first is to read the file and check its structure in order to see if there are any children in it. Keep in mind that the property ChildNodes returns only the children on the specific level of the XML DOM.
XmlDocument xDoc = new XmlDocument();
if (xDoc.ChildNodes.Count == 0) {
// It is empty
}else if (xDoc.ChildNodes.Count == 1) {
// There is only one child, probably the declaration node at the beginning
}else if (xDoc.ChildNodes.Count > 1) {
// There are more children on the **root level** of the DOM
}
The second way would be to catch the respective XMLException thrown when the document is loaded.
try
{
XmlDocument doc = new XmlDocument();
doc.Load("test.xml");
}
catch (XmlException exc)
{
//invalid file
}
Hope I helped!
You can try to load the XML into XML document and catch the exception.
Here is the sample code:
var doc = new XmlDocument();
try {
doc.LoadXml(content);
} catch (XmlException e) {
// put code here that should be executed when the XML is not valid.
}
Hope it helps.
(Or)
If you want the function (for stylistic reasons, not for performance), implement it yourself:
public class MyXmlDocument: XmlDocument
{
bool TryParseXml(string xml){
try{
ParseXml(xml);
return true;
}catch(XmlException e){
return false;
}
}
Use this function to know whether it is valid or not
Source

Editing XML file in Silverlight does not work, but why?

Im trying to open and edit XML file inside Silverlight element, but I can't edit it.
My XML file (Customers.xml) looks like this:
<?xml version="1.0"?>
<customers>
<customer>Joe</customer>
<customer>Barrel</customer>
</customers>
And my C# logic:
[...]
XDocument xdoc = XDocument.Load("Customers.xml");
xdoc.Root.Add(new XElement("customer", "Stephano")); //here I wish it to add Stephano as a customer.
using (var file = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = file.OpenFile("Customers.xml", FileMode.Create))
{
xdoc.Save(stream); //and here I wish it to save it to the file
}
}
PopulateCustomersList();
/\ here is a function that is used to display the content of XML file, it goes:
private void PopulateCustomersList()
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = new XmlXapResolver();
XmlReader reader = XmlReader.Create("Customers.xml");
reader.MoveToContent();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "customer")
{
//OutputTextBlock.Text = reader.GetAttribute("first");
customersList.Items.Add(new ListBoxItem()
{
Content = reader.ReadInnerXml()
});
}
if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "customers")
{
break;
}
}
reader.Close();
}
In my xaml file I have
<ListBox x:Name="customersList" />
so it gets displayed, but the problem is that only Joe and Barrel gets to be displayed and where is Stephano?
I got this code from various tutorials and forums, I don't quite understand it, I know it may be strange way to do that, but I just can't find out how to do that and I'm trying all sort of things. The funniest thing is that I found on many forums a way to save the file, which looks like this:
xdoc.Save("Customers.xml"); but my Visual Studio says that the arguments are wrong, because it is a string. How am I supposed to tell him that its a file?
Okay:
.Save() saves the current XDocument, I.E it's going to save the XML file you loaded up here
XDocument xdoc = XDocument.Load("Customers.xml");
So it should be something like (this is coded without any knowledge more than you provided)
XDocument xdoc = XDocument.Load("Customers.xml");
xdoc.Root.Add(new XElement("customer", "Stephano"));
xdoc.Save();
PopulateCustomersList(xdoc);
private void PopulateCustomersList(XDocument xdoc)
{
foreach(XElement in element xdoc.Root.Elements("customer"))
{
customersList.Items.Add(new ListBoxItem()
{
Content = (string)element;
}
}
}

determine if xml file contains data - c#

How do i know if my XML file has data besides the name space info:
Some of the files contain this:
<?xml version="1.0" encoding="UTF-8"?>
And if i encounter such a file, i want to place the file in an error directory
You could use the XmlReader to avoid the overhead of XmlDocument. In your case, you will receive an exception because the root element is missing.
string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
using (StringReader strReader = new StringReader(xml))
{
//You can replace the StringReader object with the path of your xml file.
//In that case, do not forget to remove the "using" lines above.
using (XmlReader reader = XmlReader.Create(strReader))
{
try
{
while (reader.Read())
{
}
}
catch (XmlException ex)
{
//Catch xml exception
//in your case: root element is missing
}
}
}
You can add a condition in the while(reader.Read()) loop after you checked the first nodes to avoid to read the entire xml file since you just want to check if the root element is missing.
I think the only way is to catch an exception when you try and load it, like this:
try
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(Server.MapPath("XMLFile.xml"));
}
catch (System.Xml.XmlException xmlEx)
{
if (xmlEx.Message.Contains("Root element is missing"))
{
// Xml file is empty
}
}
Yes, there is some overhead, but you should be performing sanity checks like this anyway. You should never trust input and the only way to reliably verify it is XML is to treat it like XML and see what .NET says about it!
XmlDocument xDoc = new XmlDocument();
if (xDoc.ChildNodes.Count == 0)
{ // xml document is empty }
if (xDoc.ChildNodes.Count == 1)
{ // in xml document is only declaration node. (if you are shure that declaration is allways at the begining }
if (xDoc.ChildNodes.Count > 1)
{ // there is declaration + n nodes (usually this count is 2; declaration + root node) }
Haven't tried this...but should work.
try
{
XmlDocument doc = new XmlDocument();
doc.Load("test.xml");
}
catch (XmlException exc)
{
//invalid file
}
EDIT: Based on feedback comments
For large XML documents see Thomas's answer. This approach can have performance issues.
But, if it is a valid xml and the program wants to process it then this approach seems better.
If you aren't worried about validity, just check to see if there is anything after the first ?>. I'm not entirely sure of the C# syntax (it's been too long since I used it), but read the file, look for the first instance of ?>, and see if there is anything after that index.
However, if you want to use the XML later or you want to process the XML later, you should consider PK's answer and load the XML into an XmlDocument object. But if you have large XML documents that you don't need to process, then a solution more like mine, reading the file as text, might have less overhead.
You could check if the xml document has a node (the root node) and check it that node has inner text or other children.
As long as you aren't concerned with the validity of the XML document, and only want to ensure that it has a tag other than the declaration, you could use simple text processing:
var regEx = new RegEx("<[A-Za-z]");
bool foundTags = false;
string curLine = "";
using (var reader = new StreamReader(fileName)) {
while (!reader.EndOfStream) {
curLine = reader.ReadLine();
if (regEx.Match(curLine)) {
foundTags = true;
break;
}
}
}
if (!foundTags) {
// file is bad, copy.
}
Keep in mind that there's a million other reasons that the file may be invalid, and the code above would validate a file consisting only of "<a". If your intent is to validate that the XML document is capable of being read, you should use the XmlDocument approach.

Categories

Resources