Get value from XML file using C# - c#

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);
}
}
}
}
​

Related

how to convert .tsv content to xml

I have a tsv file which looks like below
Time Object pmPdDrb pmPdcDlSrb
00:45 EUtranCellFDD=GNL02294_7A_1 2588007 1626
00:45 EUtranCellFDD=GNL02294_7B_1 18550 32
00:45 EUtranCellFDD=GNL02294_7C_1 26199 38
00:45 EUtranCellFDD=GNL02294_9A_1 3857243 751
Is it possible to convert this to XML like below?
<xmlnode>
<Time>00:45</Time>
<Object>EUtranCellFDD=GNL02294_7A_1</Object>
<pmPdDrb>2588007</pmPdDrb>
<pmPdcDlSrb>1626</pmPdcDlSrb>
</xmlnode>
I have tried below code:
var reader = File.ReadAllLines(logFile);
var xml1 = new XElement("TopElement",
reader.Select(line => new XElement("Item",
line.Split('\t').Select((column, index) =>
new XElement("Column" + index,column)))
)
);
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication110
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.txt";
const string OUTPUT_FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string header = "<xmlnodes></xmlnodes>";
XDocument doc = XDocument.Parse(header);
XElement xmlnodes = doc.Root;
StreamReader reader = new StreamReader(INPUT_FILENAME);
string line = "";
string[] columnNames = null;
int lineCount = 0;
while((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
string[] splitArray = line.Split(new char[] { '\t', ' '}, StringSplitOptions.RemoveEmptyEntries);
if (++lineCount == 1)
{
columnNames = splitArray;
}
else
{
XElement newNode = new XElement("xmlnode");
xmlnodes.Add(newNode);
for(int i = 0; i < splitArray.Length; i++)
{
XElement xColumn = new XElement(columnNames[i], splitArray[i]);
newNode.Add(xColumn);
}
}
}
}
doc.Save(OUTPUT_FILENAME);
}
}
}

Find string in xml and get the corresponding sister(?) nodes

I am making a tool which reads the cvc of a file, and searches the cvc value in an xml. it has multiple parent notes called release. i already managed to let it find the cvc value in the xml but i am not able to make it, that it gets the corresponding sister(sorry i dont know how its called) nodes.
This is a part of the XML:
<releases>
<release>
<id>1</id>
<name>name1</name>
<publisher></publisher>
<region>WLD</region>
<languages>en,fr,de,it,es,ru,ja</languages>
<group></group>
<imagesize>16</imagesize>
<serial>LA-H-AAAAA</serial>
<titleid>01007EF00011E000 </titleid>
<imgcrc>5DD119C1</imgcrc>
<filename>test</filename>
<releasename>test</releasename>
<trimmedsize>0</trimmedsize>
<firmware>1.0.0</firmware>
<type>1</type>
<card>1</card>
</release>
<release>
<id>2</id>
<name>name2</name>
<publisher></publisher>
<region>WLD</region>
<languages>en,fr,de,it,es,nl,pt,ru,ja</languages>
<group></group>
<imagesize>8</imagesize>
<serial>LA-H-AABPA</serial>
<titleid>0100152000022000</titleid>
<imgcrc>1912A1DF</imgcrc>
<filename>test</filename>
<releasename>test</releasename>
<trimmedsize>0</trimmedsize>
<firmware>1.0.0</firmware>
<type>1</type>
<card>1</card>
</release>
This is my code:
XmlNode node = doc.SelectSingleNode ("releases/*[contains(name(),'release')]/imgcrc[text() = '" + textBox6.Text + "']");
if (node == null)
{
XmlNode id = node.ParentNode.SelectSingleNode ("titleid");
XmlNode serial = node.ParentNode.SelectSingleNode ("serial");
XmlNode r = node.ParentNode.SelectSingleNode ("region");
XmlNode fw = node.ParentNode.SelectSingleNode ("firmware");
textBox8.Text = id.InnerText;
textBox4.Text = r.InnerText;
if (textBox4.Text == "WLD") {
textBox4.Text = "Worldwide";
}
textBox3.Text = fw.InnerText;
if (textBox3.Text == "") {
textBox3.Text = "The required FW wasn't found yet";
}
textBox2.Text = serial.InnerText;
} else {
textBox2.Text = "Game is not in the DB or you modified it";
textBox3.Text = "Game is not in the DB or you modified it";
textBox4.Text = "Game is not in the DB or you modified it";
textBox8.Text = "Game is not in the DB or you modified it";
}
Sorry if my question isnt clear enough and or the formating wrong.
If you use a path something like this, you will get the release element rather than just the imgcrc element:
var path = "releases/release[imgcrc = '"+ crc +"']";
var node = doc.SelectSingleNode(path);
Now you can grab the relevant child values from there:
if(node != null)
{
var titleId = node["titleid"].InnerText;
var serial = node["serial"].InnerText;
var region = node["region"].InnerText;
var firmware = node["firmware"].InnerText;
//etc
}
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("release").Select(x => new {
id = (int)x.Element("id"),
name = (string)x.Element("name"),
publisher = (string)x.Element("publisher"),
region = (string)x.Element("region"),
languages = (string)x.Element("languages"),
group = (string)x.Element("group"),
imagesize = (int)x.Element("imagesize"),
serial = (string)x.Element("serial"),
titleid = (string)x.Element("titleid"),
imgcrc = (string)x.Element("imgcrc"),
filename = (string)x.Element("filename"),
releasename= (string)x.Element("releasename"),
trimmedsize = (int)x.Element("trimmedsize"),
firmware = (string)x.Element("firmware"),
type = (int)x.Element("type"),
card = (int)x.Element("card")
}).ToList();
}
}
}

Repeated writing in different XMLfiles

I need to write GPS-Data in different XMLfiles. The files need to have the following format:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx>
<metadata>
<time>YYYY-MM-DDTHH:MM:SSZ</time>
</metadata>
<trk>
<name>YYYY-MM-DDTHH:MM:SSZ</name>
<trkseg>
<trkpt lat="12.1795" lon="12.3456">
<ele>-46.97</ele>
<time>YYYY-MM-DDTHH:MM:SSZ</time>
</trkpt>
// more trkpt
</trkseg>
</trk>
</gpx>
I tried to do it with an XMLwriter. At first it constructs the part till trkpt.That works. The XmlWriterSettings were included because the Error told me to use ConformanceLevel "Auto" or "fregmented" ,but that didn't solve my issue.
XmlWriterSettings setting = new XmlWriterSettings();
setting.ConformanceLevel = ConformanceLevel.Auto;
setting.Indent = true;
DateTime localDate = DateTime.Now;
xmlWriter[0] = XmlWriter.Create("testbase.xml", setting);
for (int i = 1; i < (numOfXMLWriter); i++)
{
xmlWriter[i] = XmlWriter.Create(test[i].Text, setting);
}
int tmp = 0;
foreach (XmlWriter writer in xmlWriter)
{
writer.WriteStartDocument(true);
writer.WriteStartElement("gpx");
writer.WriteStartElement("metadata");
writer.WriteStartElement("time");
writer.WriteString(localDate.Year + "-" + localDate.Month + "-" + localDate.Day + "T" + localDate.Hour + ":" + localDate.Minute + ":" + localDate.Second);
writer.WriteEndElement(); //time
writer.WriteEndElement(); //metadata
//trk + name
writer.WriteStartElement("trkseg");
}
Later the received GPS-Data is written as individual trkpt.
xmlWriter[id].WriteStartElement("trkpt");
xmlWriter[id].WriteAttributeString("lat", splitData[4]);
xmlWriter[id].WriteAttributeString("lon", splitData[6]);
xmlWriter[id].WriteStartAttribute("ele");
xmlWriter[id].WriteString("0");
xmlWriter[id].WriteEndElement(); //</ele>
xmlWriter[id].WriteStartElement("time");
xmlWriter[id].WriteString(splitData[10][4] + splitData[10][5] + "-" + splitData[10][2] + splitData[10][3] + "-" + splitData[10][0] + splitData[10][1] + "T" + splitData[2][0] + splitData[2][1] + ":" + splitData[2][2] + splitData[2][3] + ":" + splitData[2][4] + splitData[2][5] + "Z");
xmlWriter[id].WriteEndElement(); //</time>
xmlWriter[id].WriteEndElement(); //</trkpt>
The Error says:
InvalidOperationException: "Token StartElement in state EndRootElement would result in an invalid XML document”
I think this is because the XMLwriter Closes all the nodes atomatically and later i try to add another Node on root Level. Is there a possibility to stap the writer from ending the document on it's own?
Thanks for your help!
Jonas
Using 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)
{
string header = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><gpx></gpx>";
XDocument doc = XDocument.Parse(header);
XElement gpx = doc.Root;
gpx.Add(new object[] {
new XElement("metadata"), new XElement("time", DateTime.Now.ToString("yyyy-MM-ddthh:mm:ssz")),
new XElement("trk", new object[] {
new XElement("name", DateTime.Now.ToString("yyyy-MM-ddthh:mm:ssz")),
new XElement("trksseg", new object[] {
new XElement("trkpt", new object[] {
new XAttribute("lat", 12.1795),
new XAttribute("lon", 12.3456),
new XElement("ele", -46.97),
new XElement("time",DateTime.Now.ToString("yyyy-MM-ddthh:mm:ssz")),
})
})
})
});
}
}
}

Get Innertext from an XML string which has only one node without looping

I have an XML string which looks like below
<?xml version="1.0" encoding="Windows-1252"?><Product><ID>0701161476416</ID><UNIQUE_ID>test26051602</UNIQUE_ID><STATUS>DONE</STATUS></Product>
It is know that my XML string will always has a single node ans so I do not want to look, instead I would like to get Unique_ID and Status inner values without looping.
May I know a better way to do it and I do have the below code which actually loops through each node
XmlDocument xm = new XmlDocument();
xm.LoadXml(XML_STRING);
XmlNodeList xnList = xm.SelectNodes("/Product/Product");
foreach (XmlNode xn in xnList)
{
string uniqueID = xn["UNIQUE_ID"].InnerText;
string status = xn["STATUS"].InnerText;
}
There is SelectSingleNode() which you can use for this purpose :
XmlNode product = xm.SelectSingleNode("/Product/Product");
string uniqueID = product["UNIQUE_ID"].InnerText;
string status = product["STATUS"].InnerText;
Or, if Product is the root element, then you can access it from DocumentElement property of the XmlDocument :
XmlNode product = xm.DocumentElement;
string uniqueID = product["UNIQUE_ID"].InnerText;
string status = product["STATUS"].InnerText;
If you have more than one product 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
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"Windows-1252\"?>" +
"<Products>" +
"<Product>" +
"<ID>0701161476416</ID>" +
"<UNIQUE_ID>test26051603</UNIQUE_ID>" +
"<STATUS>DONE</STATUS>" +
"</Product>" +
"<Product>" +
"<ID>0701161476417</ID>" +
"<UNIQUE_ID>test26051604</UNIQUE_ID>" +
"<STATUS>DONE</STATUS>" +
"</Product>" +
"<Product>" +
"<ID>0701161476418</ID>" +
"<UNIQUE_ID>test26051605</UNIQUE_ID>" +
"<STATUS>DONE</STATUS>" +
"</Product>" +
"</Products>";
XDocument doc = XDocument.Parse(xml);
var results = doc.Descendants("Product").Select(x => new
{
id = (long)x.Element("ID"),
uniqueID = (string)x.Element("UNIQUE_ID"),
status = (string)x.Element("STATUS")
}).ToList();
}
}
}
This could work, but I guess there is a better solution:
XDocument xm = XDocument.Parse(XML_STRING);
var product = xm.Element("Product").Element("Product");
string uniqueID = product.Element("UNIQUE_ID").Value;
string status = product.Element("STATUS").Value;
Your SelectNodes line seemed wrong for the sample Xml.
XmlNodeList xnList = xm.SelectNodes("/Product");
if (xnList.Count > 0)
{
string uniqueID = xnList[0]["UNIQUE_ID"].InnerText;
string status = xnList[0]["STATUS"].InnerText;
}

Reading xml document with several nodes

I have used the following code before but my xml is different this time:
protected string ReturnXmlValue(XmlDocument myXDoc, string field)
{
var retval = string.Empty;
try
{
var node = myXDoc.GetElementsByTagName(field);
if (node.Count > 0)
{
var xmlNode = node.Item(0);
if (xmlNode != null)
{
retval = xmlNode.InnerText;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
throw;
}
return retval;
}
Here is an example of my xml file dummied down a bit:
<RichDBDS>
<TrxDetailCard>
<TRX_HD_Key>18683435</TRX_HD_Key>
<Date_DT>2015-10-22T21:32:00.233+00:00</Date_DT>
<TRX_Card_Key>15263569</TRX_Card_Key>
<Total_Amt_MN>22.0000</Total_Amt_MN>
<Result_CH>0 </Result_CH>
<Result_Txt_VC>APPROVED</Result_Txt_VC>
<Approval_Code_CH>0943253</Approval_Code_CH>
</TrxDetailCard>
<TrxDetailCard>
<TRX_HD_Key>18683825</TRX_HD_Key>
<Date_DT>2015-10-23T21:32:00.233+00:00</Date_DT>
<TRX_Card_Key>15263569</TRX_Card_Key>
<Total_Amt_MN>32.0000</Total_Amt_MN>
<Result_CH>0 </Result_CH>
<Result_Txt_VC>APPROVED</Result_Txt_VC>
<Approval_Code_CH>093389</Approval_Code_CH>
</TrxDetailCard>
</RichDBDS>
I've not worked with xml much so I'm not sure how to search this for a specific amount. I can have several TrxDetailCards. I know how to get amount when I only have one TrxDetailCard but I need to return the TrxDetailCard for the hits on the amount that I need.
So if I am looking for the TrxDetailCard that is 32.00, I need the method to return:
<TrxDetailCard>
<TRX_HD_Key>18683825</TRX_HD_Key>
<Date_DT>2015-10-23T21:32:00.233+00:00</Date_DT>
<TRX_Card_Key>15263569</TRX_Card_Key>
<Total_Amt_MN>32.0000</Total_Amt_MN>
<Result_CH>0 </Result_CH>
<Result_Txt_VC>APPROVED</Result_Txt_VC>
<Approval_Code_CH>093389</Approval_Code_CH>
</TrxDetailCard>
How would I go about doing this?
Try this
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 =
"<RichDBDS>" +
"<TrxDetailCard>" +
"<TRX_HD_Key>18683435</TRX_HD_Key>" +
"<Date_DT>2015-10-22T21:32:00.233+00:00</Date_DT>" +
"<TRX_Card_Key>15263569</TRX_Card_Key>" +
"<Total_Amt_MN>22.0000</Total_Amt_MN>" +
"<Result_CH>0 </Result_CH>" +
"<Result_Txt_VC>APPROVED</Result_Txt_VC>" +
"<Approval_Code_CH>0943253</Approval_Code_CH>" +
"</TrxDetailCard>" +
"<TrxDetailCard>" +
"<TRX_HD_Key>18683825</TRX_HD_Key>" +
"<Date_DT>2015-10-23T21:32:00.233+00:00</Date_DT>" +
"<TRX_Card_Key>15263569</TRX_Card_Key>" +
"<Total_Amt_MN>32.0000</Total_Amt_MN>" +
"<Result_CH>0 </Result_CH>" +
"<Result_Txt_VC>APPROVED</Result_Txt_VC>" +
"<Approval_Code_CH>093389</Approval_Code_CH>" +
"</TrxDetailCard>" +
"</RichDBDS>";
XElement richDBDS = XElement.Parse(xml);
XElement results = richDBDS.Elements("TrxDetailCard").Where(x => (decimal)x.Element("Total_Amt_MN") == (decimal)32.0000).FirstOrDefault();
}
}
}
​
You can use Linq-to-Xml
var str = File.ReadAllText(#"C:\YourDirectory\sample.xml");
XDocument xDoc = XDocument.Parse(str);
var trxNodes = xDoc.Descendants("TrxDetailCard");
var node = trxNodes.First(n => double.Parse(n.Element("Total_Amt_MN").Value) == 32.00);

Categories

Resources