I have a text file contains 500+ xmlelements like the following:
<Data a="a" b="b" c="c" d="d"><Date runDt="01-01-1900" /></Data>
Can someone please show me how to read/load it so I can retrieve certain attributes/elements? And once I manipulate the data, write it back to a new text file (and needs to be a .txt file without any xml headers).
Thanks :)
Easiest way is to use:
using System.Xml;
XmlDocument xml = new XmlDocument ();
xml.InnerXml = #"<Data a=\"a\" b=\"b\" c=\"c\" d=\"d\"><Date runDt=\"01-01-1900\" /></Data>";
Console.WriteLine (xml.ChildNodes [0].Attributes [0].InnerText);
Will print
a
Using XmlDocument is very easy, just check its fields, variables and methods.
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<Data a=\"a\" b=\"b\" c=\"c\" d=\"d\"><Date runDt=\"01-01-1900\" /></Data>\n" +
"<Data a=\"a\" b=\"b\" c=\"c\" d=\"d\"><Date runDt=\"01-01-1900\" /></Data>\n" +
"<Data a=\"a\" b=\"b\" c=\"c\" d=\"d\"><Date runDt=\"01-01-1900\" /></Data>\n" +
"<Data a=\"a\" b=\"b\" c=\"c\" d=\"d\"><Date runDt=\"01-01-1900\" /></Data>\n" +
"<Data a=\"a\" b=\"b\" c=\"c\" d=\"d\"><Date runDt=\"01-01-1900\" /></Data>\n";
//xml can only contain one root tag. Need to wrap xml in root tag if one is missing
input = string.Format("<Root>{0}</Root>", input);
XDocument doc = XDocument.Parse(input);
// if loading from file
//string input = File.ReadAllText(filename);
//input = string.Format("<Root>{0}</Root>", input);
//XDocument doc = XDocument.Load(filename);
var results = doc.Descendants("Data").Select(x => new
{
a = x.Attribute("a").Value,
b = x.Attribute("b").Value,
c = x.Attribute("c").Value,
d = x.Attribute("d").Value,
date = DateTime.Parse(x.Element("Date").Attribute("runDt").Value)
}).ToList();
}
}
}
Related
In an xsl-fo file how can I remove some elements
Quickest way, perhaps not the most elegant :
XmlDocument xmlDoc = new XmlDocument();
StringBuilder xmlSb = new StringBuilder();
xmlSb.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
xmlSb.AppendLine("<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">");
xmlSb.AppendLine(" <fo:layout-master-set>");
xmlSb.AppendLine(" <fo:simple-page-master master-name=\"master\">");
xmlSb.AppendLine(" <fo:region-body margin-bottom=\"0.5in\" margin-top=\"0.9in\" margin-left=\"35pt\"/>");
xmlSb.AppendLine(" <fo:region-before region-name=\"xsl-region-before\" extent=\"0.9in\"/>");
xmlSb.AppendLine(" <fo:region-after region-name=\"xsl-region-after\" extent=\"0.5in\"/>");
xmlSb.AppendLine(" </fo:simple-page-master>");
xmlSb.AppendLine(" </fo:layout-master-set>");
xmlSb.AppendLine(" <fo:page-sequence master-reference=\"master\"/>");
xmlSb.AppendLine("</fo:root>");
// Load xml from string
xmlDoc.LoadXml(xmlSb.ToString());
Console.WriteLine("----- Original xml -----");
Console.WriteLine(xmlSb.ToString());
// Select region-before node
XmlNode regionBeforeNode = xmlDoc.SelectSingleNode("//*[local-name()='region-before']");
// Remove region-before node
regionBeforeNode.ParentNode.RemoveChild(regionBeforeNode);
// Select region-after node
XmlNode regionAfterNode = xmlDoc.SelectSingleNode("//*[local-name()='region-after']");
// Remove region-after node
regionAfterNode.ParentNode.RemoveChild(regionAfterNode);
Console.WriteLine("----- Nodes removed -----");
StringBuilder sbOut = new StringBuilder();
// Pretty indented output
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.Replace
};
using (XmlWriter writer = XmlWriter.Create(sbOut, settings))
{
xmlDoc.Save(writer);
}
Console.WriteLine(sbOut.ToString ());
Try xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">" +
" <fo:layout-master-set>" +
" <fo:simple-page-master master-name=\"master\">" +
" <fo:region-body margin-bottom=\"0.5in\" margin-top=\"0.9in\" margin-left=\"35pt\"/>" +
" </fo:simple-page-master>" +
" </fo:layout-master-set>" +
" <fo:page-sequence master-reference=\"master\"/>" +
"</fo:root>";
XDocument doc = XDocument.Parse(xml);
XNamespace nsFo = doc.Root.GetNamespaceOfPrefix("fo");
XElement regionBody = doc.Descendants(nsFo + "region-body").FirstOrDefault();
regionBody.Add(new XElement(nsFo + "test", new object[] { new XAttribute("name", "John")}));
}
}
}
How do I add the char : to an XML element attribute?
Here is how the output should look like
<alto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.loc.gov/standards/alto/ns-v3#"
xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v3# http://www.loc.gov/standards/alto/v3/alto-3-1.xsd" SCHEMAVERSION="3.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
and so far this is my code
var z = doc.Descendants("alto").First();
XNamespace ns = "http://www.w3.org/2001/XMLSchema-instance";
z.Add(new XAttribute(XNamespace.Xmlns + "xsi", ns.NamespaceName));
I tried this code, but it gives me error
new XAttribute("xmlns", "http://www.loc.gov/standards/alto/ns-v3#")
and here is the error message:
The prefix '' cannot be redefined from '' to 'http://www.loc.gov/standards/alto/ns-v3#' within the same start element tag
You should put default namespace last. For complex namespaces like yours I usually just parse the string like code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<alto xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns=\"http://www.loc.gov/standards/alto/ns-v3#\"" +
" xsi:schemaLocation=\"http://www.loc.gov/standards/alto/ns-v3# http://www.loc.gov/standards/alto/v3/alto-3-1.xsd\" SCHEMAVERSION=\"3.1\"" +
" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" +
"</alto>";
XDocument doc = XDocument.Parse(xml);
XElement root = doc.Root;
XNamespace ns = root.GetDefaultNamespace();
XNamespace nsXsi = root.GetNamespaceOfPrefix("xsi");
XNamespace nsSchemaLocation = root.GetNamespaceOfPrefix("schemaLocation");
XNamespace nsXlink = root.GetNamespaceOfPrefix("xlink");
}
}
}
But it gives me exception like "There are multiple root elements. Line 3, position 2." on the line reader.MoveToContent();
Below is the sample code that i use
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace sample
{
class Program
{
static void Main(string[] args)
{
System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader("C:\\Users\\ADMIN\\Pictures\\test.xml");
string contents = "";
while (reader.Read())
{
reader.MoveToContent();
if (reader.NodeType == System.Xml.XmlNodeType.Element)
contents += "<" + reader.Name + ">\n";
if (reader.NodeType == System.Xml.XmlNodeType.Text)
contents += reader.Value + "\n";
}
Console.Write(contents);
Console.ReadLine();
}
}
}
please help.
You are trying to parse an XML document, that, stand-alone, isn't valid XML. Therefore, you need to tell it that it is only a fragment. This will prevent it from throwing an error about multiple root elements.
You can do this by replacing the line
System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader("C:\\Users\\ADMIN\\Pictures\\test.xml");
with:
var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
var reader = System.Xml.XmlTextReader.Create("C:\\Users\\ADMIN\\Pictures\\test.xml", settings);
I am building a Chat parser that should replace XML tags (in a string) describing an emoticon with HTML image tags having a link to the related emoticon file.
Example Chat Text:
Hi there <ss type="tongueout">:p</ss><ss type="laugh">:D</ss>
Should be changed to the following:
Hi there <img src="./Emoticons/toungeout.png" /><img src="./Emoticons/laugh.png" />
The image files are all named like the corresponding "type"-attribute.
Here's what I have tried so far:
var smilies = XElement.Parse(text)
.Descendants("ss")
.Select(x => x.Attribute("type").Value);
Regex.Replace(text, "<.*?>", String.Empty);
foreach (var smily in smilies)
{
text += "<img src=\"./Emoticons/" + smily + ".png\" />";
}
This added all smilies at the end of the text, but is not capable of putting them within the text.
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
namespace ConsoleApplication53
{
class Program
{
static void Main(string[] args)
{
string xml =
"<Root>" +
"<ss type=\"tongueout\">:p</ss><ss type=\"laugh\">:D</ss>" +
"</Root>";
XElement root = XElement.Parse(xml);
XElement[] img = new XElement[] {
new XElement("img", new XAttribute("src","./Emoticons/toungeout.png")),
new XElement("img", new XAttribute("src", "./Emoticons/laugh.png"))
};
XElement ss = root.Element("ss");
ss.ReplaceWith(img);
}
}
}
I finally found a solution:
string[] split = Regex.Split(text, "</ss>");
text = "";
foreach (string s in split)
{
Regex regex = new Regex(#"(?<=\btype="")[^""]*");
string smily = regex.Match(s).Value;
string result = Regex.Replace(s, #"<(.|\n)*?>", string.Empty);
writer.WriteEncodedText(result);
if (smily != string.Empty)
{
writer.AddAttribute(HtmlTextWriterAttribute.Src, "./Emoticons/" + smily + ".png");
writer.RenderBeginTag(HtmlTextWriterTag.Img);
}
}
I want to fetch only 'Param1' from the below XML file.Please help.With my code it is giving me complete string of values of all attributes under SSIS Parameter Node but t is not giving Param1 in that.
XML File Contents:`
<?xml version="1.0"?>
<SSIS:Parameters xmlns:SSIS="www.microsoft.com/SqlServer/SSIS">
<SSIS:Parameter
SSIS:Name="param1">
<SSIS:Properties>
<SSIS:Property
SSIS:Name="ID">{6fc5a81b-723b-4821-b948-0cbd44d86c84}</SSIS:Property>
<SSIS:Property
SSIS:Name="CreationName"></SSIS:Property>
<SSIS:Property
SSIS:Name="Description"></SSIS:Property>
<SSIS:Property
SSIS:Name="IncludeInDebugDump">0</SSIS:Property>
<SSIS:Property
SSIS:Name="Required">0</SSIS:Property>
<SSIS:Property
SSIS:Name="Sensitive">0</SSIS:Property>
<SSIS:Property
SSIS:Name="Value"></SSIS:Property>
<SSIS:Property
SSIS:Name="DataType">18</SSIS:Property>
</SSIS:Properties>
</SSIS:Parameter>
</SSIS:Parameters>
`
My Code Snippet:
XmlDataDocument xmldoc = new XmlDataDocument();
XmlNodeList xmlnode;
int i = 0;
string str = null;
FileStream fs = new FileStream(#"D:\Sample SSIS\sampleDeploymentDemo\sampleDeploymentDemo\Project.params", FileMode.Open, FileAccess.Read);
xmldoc.Load(fs);
xmlnode = xmldoc.GetElementsByTagName("SSIS:Parameters");
for (i = 0; i <= xmlnode.Count - 1; i++)
{
xmlnode[i].ChildNodes.Item(0).InnerText.Trim();
str = xmlnode[i].InnerText.Trim() + " " + xmlnode[i].ChildNodes.Item(1).InnerText.Trim() + " " + xmlnode[i].ChildNodes.Item(2).InnerText.Trim();
Console.WriteLine(str);
}
Console.ReadLine();
"param1" is attribute. You can get it with followed code:
...
xmlnode = xmldoc.GetElementsByTagName("SSIS:Parameters");
for (i = 0; i <= xmlnode.Count - 1; i++)
{
var val = xmlnode[i].FirstChild.Attributes["SSIS:Name"].Value;
Console.WriteLine(val);
}
Console.ReadLine();
...
See this link
Try XML Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants().Where(x => x.Name.LocalName == "Parameter").Descendants().Where(y => y.Name.LocalName == "Property").Select(z => new
{
value = z.Attributes().Where(a => a.Name.LocalName == "Name").Select(b => b.Value).FirstOrDefault()
}).ToList();
foreach (var item in results)
{
Console.WriteLine(item.value);
}
}
}
}