I am writing a program that reads a XML file with Visual C#. I have a problem reading the Xml file, because it contains invalid XML symbols, for example '&'.
I have to read the XML but I can not modify the document. How can I modify the Xml file using C#? My code so far:
private void button1_Click(object sender, EventArgs e)
{
XmlDocument doc;
doc = new XmlDocument();
doc.Load("nuevo.xml");
XmlNodeList Xpersonas = doc.GetElementsByTagName("personas");
XmlNodeList Xlista = ((XmlElement)Xpersonas[0]).GetElementsByTagName("edad");
foreach (XmlElement nodo in Xlista)
{
string edad = nodo.GetAttribute("edad");
string nombre = nodo.InnerText;
textBox1.Text = nodo.InnerXml;
}
As #EBrown suggested, one possibility would be read the file content in a string variable and replace the & symbol with the correct representation for propert XML & and then parse the XML structure. A possible solution could look like this:
var xmlContent = File.ReadAllText(#"nuevo.xml");
XmlDocument doc;
doc = new XmlDocument();
doc.LoadXml(xmlContent.Replace("&", "&"));
XmlNodeList Xpersonas = doc.GetElementsByTagName("personas");
XmlNodeList Xlista = ((XmlElement)Xpersonas[0]).GetElementsByTagName("edad");
foreach (XmlElement nodo in Xlista)
{
string edad = nodo.GetAttribute("edad");
string nombre = nodo.InnerText;
Console.WriteLine(nodo.InnerXml.Replace("&", "&"));
}
The output is:
34 & 34
If it is ok to use LINQ2XML, then the solution is even shorter, and there is no need to write the reverse(second) replace, because LINQ2XML make this for you automatically:
var xmlContent = File.ReadAllText(#"nuevo.xml");
var xmlDocument = XDocument.Parse(xmlContent.Replace("&", "&"));
var edad = xmlDocument.Root.Element("edad").Value;
Console.WriteLine(edad);
The output is the same as above.
Related
this is the code
XmlDocument xml = new XmlDocument();
XmlElement root = xml.CreateElement("customers");
xml.AppendChild(root);
foreach (var cust in customerlist)
{
XmlElement child = xml.CreateElement("customer");
child.SetAttribute("CustomerId", cust.CustomerId.ToString());
child.SetAttribute("CustomerName", cust.CustomerName);
child.SetAttribute("PhoneNumber", cust.PhoneNumber);
child.SetAttribute("Email", cust.Email);
root.AppendChild(child);
}
string s = xml.OuterXml;
I want my string to have next lines added to it instead of a single xml document
My string is coming as continuous
< x >xxxxx< /x > < x >xxxxx< /x >
You can use the XmlTextWriter class to format the XML as a string like this:
StringWriter string_writer = new StringWriter();
XmlTextWriter xml_text_writer = new XmlTextWriter(string_writer);
xml_text_writer.Formatting = Formatting.Indented;
xml.WriteTo(xml_text_writer); // xml is your XmlDocument
string formattedXml = string_writer.ToString();
static void Main(string[] args)
{
WebClient _httpReq = new WebClient(); // to talk to the web only for get method
string response = _httpReq.DownloadString("https://open-ic.epic.com/FHIR/api/FHIR/DSTU2/Patient?family=Argonaut&given=Jason");
Console.WriteLine(response);\\prints the xml string fetched from FHIR provider EPIC
XmlDocument xml = new XmlDocument();
xml.LoadXml(response); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/entry/resource/patient/name");
// here code is trying to extract the name attribute
foreach (XmlNode xn in xnList)
{
string firstName = xn["family value"].InnerText;
string lastName = xn["given value"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
//print the first name and last name of the patient
}
Console.ReadLine();
}
i do it like this:
XmlDocument MyDocument = new XmlDocument();
MyDocument.Load("...");
XmlNode MyNode = MyDocument.SelectSingleNode("/Node_Name");
foreach (XmlAttribute MyAttribute in MyNode.Attributes)
{
if (MyAttribute.Name == "Attribute_Name")
{
object Value = MyAttribute.Value;
break;
}
}
Review XPath. Once you start understanding it, you will find it efficient and easier to code than iterating through lists. It also lets you directly get the nodes/attributes you want.
Then the code would be something similar to
string attrVal = doc.SelectSingleNode("/entry/resource/patient/#name").Value;
Or you can Load XML in XMlDocument and You can fetch element and out of that element you can read specific atairbute,
XmlDocument doc = new XmlDocument();
doc.LoadXml("<reply success=\"true\">More nodes go here</reply>");
XmlElement root = doc.DocumentElement;
string s = root.Attributes["success"].Value;
I am reading a .docx file using OpenXML in C#. It reads everything correctly but strangely, the content of textbox is being read thrice. What could be wrong? Here is the code to read .docx:
public static string TextFromWord(String file)
{
const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
StringBuilder textBuilder = new StringBuilder();
using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(file, false))
{
// Manage namespaces to perform XPath queries.
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("w", wordmlNamespace);
// Get the document part from the package.
// Load the XML in the document part into an XmlDocument instance.
XmlDocument xdoc = new XmlDocument(nt);
xdoc.Load(wdDoc.MainDocumentPart.GetStream());
XmlNodeList paragraphNodes = xdoc.SelectNodes("//w:p", nsManager);
foreach (XmlNode paragraphNode in paragraphNodes)
{
XmlNodeList textNodes = paragraphNode.SelectNodes(".//w:t", nsManager);
foreach (System.Xml.XmlNode textNode in textNodes)
{
textBuilder.Append(textNode.InnerText);
}
textBuilder.Append(Environment.NewLine);
}
}
return textBuilder.ToString();
}
The part of file I am talking about is:
The result is: I read it in a test application like this:
What's wrong here?
I want to read an XML file and match tag </contrib-group> and write a string after this tag
string Final = File.ReadAllText(Npath);
string Oxml = path + "\\" + Oword + ".abs.xml";
if (File.Exists(Oxml))
{
StreamReader xml = new StreamReader(Oxml,Encoding.UTF8);
string xmltag = xml.ReadToEnd();
//File.OpenWrite(Oxml);
xml.Close();
StreamWriter write = new StreamWriter(Oxml, true, Encoding.UTF8);
Match tag = Regex.Match(xmltag, #"</contrib-group>");
if (tag.Success == true)
{
write.WriteLine(Environment.NewLine);
write.Write(Final);
}
}
So I need to write the string Final to the XML file called Oxml after the matched XML tag </contrib-group>
If you are willing to save the new content as a valid XML file which you can work with, you should use the XML classes for that approach, this should look like this (untested):
XmlDocument doc = new XmlDocument();
doc.Load("YourFile.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList elemList = root.GetElementsByTagName("contrib-group");
for (int i=0; i < elemList.Count; i++)
{
XmlNode xnode = elemList[i];
XmlNode xnodeParent = xnode.ParentNode;
XMLNode newNode = doc.CreateNode(XmlNodeType.Element, "NodeName", "");
newNode.InnerText = "ContentInsideTheNode";
xnodeParent.InsertAfter(newNode, xnode);
}
doc.Save("YourFile.xml");
If you only need to replace the string for other purposes than saving it where having a valid XML is not an issue you can just handle it as a string and use the String.Replace (String, String) Method
string searchedTag = #"</contrib-group>";
string tagAndNewContent = #"</contrib-group>" + newContent;
string fileContentString = File.ReadAllText("YourFile.xml");
string ouput = fileContentString.Replace(searchedTag, tagAndNewContent);
XML File:
<?xml version="1.0" encoding="utf-16"?>
<XMLFILE>
<Active>0</Active>
<Hits_Method>1</Hits_Method>
</XMLFILE>
What i'm trying to do is on Form1_Load get the value of ComboBox4 from XML File (Hits_Method) and when the program start to show me the value. i try something like this but didn't work out
// ------------------- StartUP Load
private void Form1_Load(object sender, EventArgs e)
{
// --------------- Read XML File / Data: Settings_Ads_General
String xmlfile = "Settings_General.xml";
XmlTextReader xreader = new XmlTextReader(xmlfile);
string comboBox4Value = xreader.GetAttribute("Hits_Method");
comboBox4.SelectedIndex = comboBox4Value;
}
Try this instead:
private void Form1_Load(object sender, EventArgs e)
{
// --------------- Read XML File / Data: Settings_Ads_General
String xmlfile = "Settings_General.xml";
XmlDocument doc = new XmlDocument();
doc.Load(xmlfile);
string comboBox4Value = doc.SelectSingleNode("XMLFILE/Hits_Method").InnerText;
comboBox4.SelectedIndex = Convert.ToInt32(comboBox4Value);
}
The SelectSingleNode method extracts data based on an XPath expression. And "XMLFILE/Hits_Method" is the XPath that leads to your value.
I will use XmlDocument and XmlNode classes.
{
String sPath = "file.xml"
XmlDocument doc = new XmlDocument();
doc.Load(sPath)
XmlNode node = doc.SelectSingleNode("XMLFILE/Hits_Method");
if (node != null)
comboBox4.SelectedIndex = node.InnerText;
}