Changing value in dtsConfig file from c# code - c#

I have a dtsConfig file with configuration for ssis package variable User::Quote_ID:
<Configuration ConfiguredType="Property"
Path="\Package.Variables[User::Quote_ID].Properties[Value]"
ValueType="String"><ConfiguredValue>77777</ConfiguredValue></Configuration>
I want to change this value from c# code:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
XmlNode xFile = xDoc.SelectSingleNode("User::Quote_ID");
xFile.Value = quote_ID.ToString();
xDoc.Save(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
xDoc = null;
It gives me an error on the third line of my code (XmlNode...):
‘User::Quote_ID’ has an invalid token
What is wrong?

Chris! Your code helped me a lot! In my case it did not work thought. I ran the application in debug mode and I could see that xDoc.Load... opens the right file, but it did not execute foreach loop. The property listOfConfigurationNodes had Count = 0. I checked my xml file again and found that it has outer node and all nodes inside this outer node. So I changed your code
XmlNodeList listOfConfigurationNodes = xDoc.SelectNodes("Configuration");
I made:
XmlNode XMLOuterNode = xDoc.SelectSingleNode("DTSConfiguration");
XmlNodeList listOfConfigurationNodes = XMLOuterNode.SelectNodes("Configuration");
This code works fine for my particular case. Thanks a lot!!!

The node name is "Configuration". Within that, you have an attribute called "Path", whose value is "\Package.Variables[User::Quote_ID].Properties[Value]".
I'm not sure what you need to do in your code, but here is an example of one way to go about making changes in that value:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
XmlNode xFile = xDoc.SelectSingleNode("Configuration");
xFile.Attributes["Path"].Value = xFile.Attributes["Path"].Value.Replace("User::Quote_ID", "newValue");
xDoc.Save(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
xDoc = null;
The above example will change \Package.Variables[User::Quote_ID].Properties[Value] to \Package.Variables[newValue].Properties[Value].
Updated Example
This will replace the 77777 value with quote_ID.ToString() (I'm assuming the 55555 is in there) for the first node (for all nodes, remove break;) where the 'Path' is \Package.Variables[User::Quote_ID].Properties[Value].
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
XmlNodeList listOfConfigurationNodes = xDoc.SelectNodes("Configuration");
foreach (XmlNode node in listOfConfigurationNodes)
{
if (node.Attributes["Path"].Value == #"\Package.Variables[User::Quote_ID].Properties[Value]")
{
node.SelectSingleNode("ConfiguredValue").InnerText = quote_ID.ToString();
break;
}
}
xDoc.Save(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
xDoc = null;

Related

Copy Node and change Value of an Attribute

I have the following XML File. I want to copy a new "Test" and change the ID of the Test. How is it possible?
I already can copy the nodes, unfortunately not on the correct position (see images) and I also can´t change the ID.
Anyone have a solution for me?
Before:
After:
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(Before.xml");
XmlNode Set = xmldoc.DocumentElement;
string strXmlQuery = "/Toolings/Testing/Test1";
XmlNode NodeToCopy = Set.SelectSingleNode(strXmlQuery);
XmlNode NewNode = NodeToCopy.CloneNode(true);
NodeToCopy.AppendChild(NewNode);
Set.InsertAfter(NewNode, Set.LastChild);
XPathNavigator navigator = xmldoc.CreateNavigator();
navigator.MoveToRoot();
navigator.MoveToFirstChild();
navigator.MoveToFirstChild();
navigator.MoveToFirstChild();
navigator.MoveToFirstChild();
navigator.SetValue("5678");
xmldoc.Save(After.xml");
Here is an example using System.Xml.Linq.XDocument which is a much easier API than XmlDocument:
//You can also use Load(), this is just so I didn't have to make a file
XDocument doc = XDocument.Parse("<Toolings><Testing><Test><ID>1234</ID></Test></Testing></Toolings>");
//Grab the first Test node (change the predicate if you have other search criteria)
var elTest = doc.Descendants().First(d => d.Name == "Test");
//Copy the node, only necessary if you don't know the structure at design time
XElement el = new XElement(elTest);
el.Element("ID").Value = "5678";
//inject new node
elTest.AddAfterSelf(el);
doc.Save("After.xml");

Can't parse XML data with C#

I have been trying to extract one value from a XML file, and then store it on the same file but in another node, I tried all the examples i've found on the net, read XPath Syntax documentation like hell and still can't get it to work.
I must take the <Documento ID="F60T33"> ID Value (which may vary) and copy it into <Reference URI="#F60T33">.
But I can't even do that if I can't manage to parse the lines, most of times node/variables/"", or I get an "object reference not established as object instance error".
Here's the code:
// Create a new XML document.
XmlDocument xmlDoc = new XmlDocument();
// Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(pfile);
//TEST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PROBLEMA
XmlNodeList Documentos = xmlDoc.GetElementsByTagName("//Documento");
XmlNodeList DatosDocumento = ((XmlElement)Documentos[0]).GetElementsByTagName("ID");
foreach (XmlElement nodo in DatosDocumento)
{
int I = 0;
XmlNodeList ID = nodo.GetElementsByTagName("ID");
Console.WriteLine("Elemento nombre ... {0}}", ID[i].InnerText);
}
//
XmlNodeList nodes = xmlDoc.SelectNodes("EnvioDTE");
XmlNode nodesimple = xmlDoc.SelectSingleNode("EnvioDTE");
Console.WriteLine("Lista Nodos: " + nodes.Count);
Console.WriteLine("Nodo Simple: " + nodesimple.InnerText);
foreach (XmlNode node in nodes)
{
string id = node.Attributes["ID"].InnerText;
Console.WriteLine(id);
}
I am almost certain the problem is on the XPath Syntax, but I can't get it to work.
Sadly I can't use XDocument as im using .NET 3.5 for this task, I would really appreciate some help on this, by behand apologize my bad english
As the XML file is too big, I'll put it here on this URL
http://puu.sh/bVNDc/31e4da5a26.xml
If you can get your references right for using System.Linq.XDocument you can do:
string idValue = xDocument.XPathSelectElement("//EnvioDTE/SetDTE")
.Attributes().SingleOrDefault(a => a.Name == "ID").Value;

Confused in getting nested elements and values via XmlDocument

I am trying to access quite a deep XML file, yet I get confused and just brute forced access to an element to get the elements within it, My problem is, it does not work (Object reference not set to an instance of an object) and my method of getting the "dictory" of the XML looks very inefficient,
My goal is to grab all the <ramStick> via a foreach loop since it can have 1-* ramSticks
Here is part of my C# code that I am having an issue with:
XmlDocument doc = new XmlDocument();
string xmlFilePath = #"C:\xampp\htdocs\userInfo.xml";
doc.Load(xmlFilePath);
XmlNodeList accountList = doc.GetElementsByTagName("account");
foreach (XmlNode node in accountList)
{
XmlElement accountElement = (XmlElement)node;
// I got inside this loop at this point and can get an accountElement with values
String hostname = accountElement.GetElementsByTagName("user")[0].InnerText;
// This is where I get confused and don't know what I am really doing and I just experiment
XmlNode accountRoot = accountElement.GetElementsByTagName("systemInfo")[0];
XmlElement ramNode = (XmlElement)accountRoot;
XmlNode ramInfo = ramNode.GetElementsByTagName("ramInfo")[0];
XmlElement ramList = (XmlElement)ramInfo;
XmlNodeList ramStick = ramList.GetElementsByTagName("ramStick");
// I want to run a foreach loop on each ramStick to get the values
foreach (XmlNode ramNodeForLoop in ramStick)
{
XmlElement ramData = (XmlElement)ramNodeForLoop;
String partNumber = ramData.GetElementsByTagName("partNumber")[0].InnerText;
}
}`
I have quite a big XML file which contains multiple <account> here is a sample of it:
<account>
<user>OYSTER-PC</user>
<systemInfo>
<dskInfo>
<dskInterface>
<deviceID>C:</deviceID><description>Local Fixed Disk</description><size>500000878592</size><freeSpace>377396776960</freeSpace><fileSystem>NTFS</fileSystem><volumeSerialNumber>4C922158</volumeSerialNumber>
</dskInterface>
<dskInterface>
<deviceID>D:</deviceID><description>CD-ROM Disc</description><size/><freeSpace/><fileSystem/><volumeSerialNumber/>
</dskInterface>
<dskInterface>
<deviceID>E:</deviceID><description>CD-ROM Disc</description><size/><freeSpace/><fileSystem/><volumeSerialNumber/>
</dskInterface>
</dskInfo>
<hddInfo>
<hddInterface>
<model>ST9500325AS ATA Device</model><interfaceType>IDE</interfaceType><name>\\.\PHYSICALDRIVE0</name><partitions>1</partitions><serialNumber>2020202020202020202020205636384547535146</serialNumber><status>OK</status>
</hddInterface>
</hddInfo>
<nicInfo>
<nicInterface>
<macAddress>48:5D:60:03:88:04</macAddress><description>Atheros AR9285 Wireless Network Adapter</description><ipAddress>192.168.1.10</ipAddress><ipSubnet>255.255.255.0</ipSubnet><defaultIpGateway>192.168.1.1</defaultIpGateway><dhcpServer>192.168.1.1</dhcpServer>
</nicInterface>
<nicInterface>
<macAddress>74:F0:6D:A8:4E:32</macAddress><description>Bluetooth Device (Personal Area Network)</description><ipAddress/><ipSubnet/><defaultIpGateway/><dhcpServer/></nicInterface>
<nicInterface>
<macAddress>20:41:53:59:4E:FF</macAddress><description>RAS Async Adapter</description><ipAddress/><ipSubnet/><defaultIpGateway/><dhcpServer/>
</nicInterface>
<nicInterface>
<macAddress>20:CF:30:55:0C:EF</macAddress><description>JMicron PCI Express Gigabit Ethernet Adapter</description><ipAddress/><ipSubnet/><defaultIpGateway/><dhcpServer/>
</nicInterface>
</nicInfo>
<ramInfo>
<ramStick>
<partNumber>M471B5273DH0-CK0 </partNumber><serialNumber>E2CE33AF</serialNumber><capacity>4294967296</capacity>
</ramStick>
<ramStick>
<partNumber>M471B5273DH0-CK0 </partNumber><serialNumber>630155D0</serialNumber><capacity>4294967296</capacity>
</ramStick>
</ramInfo>
</systemInfo>
</account>
You can use xpath like this:
foreach (XmlElement element in doc.SelectNodes("//account/systemInfo/ramInfo/ramStick"))
{
string partNumber = element["partNumber"].InnerText;
}
Note that since this call to SelectNodes returns only XmlElement, I can use XmlElement as type for the loop variable. Otherwise I'd have to use XmlNode.
After recoding so much,
Here is what I finally did...
XmlNode systemInfo = node.SelectSingleNode("systemInfo");
XmlNode ramInfo = systemInfo.SelectSingleNode("ramInfo");
XmlNodeList ramList = ramInfo.SelectNodes("ramStick");
foreach (XmlElement ramStick in ramList)
{
// add code here
}

Properly Update an XmlNode within an XmlDocument

I have been waging war with XmlDocuments all day. They are winning. I am building a component in .net 2.0 and am therefore forced to use it. Please take a look at this and help me regain some sanity:
private static string UpdateMeterAccessXml(string meterAccess, int childToUpdate, string field, string value)
{
var doc = new XmlDocument();
doc.LoadXml(meterAccess);
var xpath = String.Format("/items/item[{0}]/{1}", childToUpdate, field);
var modNode = doc.SelectSingleNode(xpath);
modNode.InnerText = value;
doc.ReplaceChild(modNode, doc.SelectSingleNode(xpath));
return doc.OuterXml;
}
doc.ReplaceChild yields an ArgumentException ("The node to be removed is not a child of this node.")
I thought that since an XmlDocument was a reference type I wouldn't have to try to swap out nodes, but if I just update the InnerText of the Node I want, doc.OuterXml doesn't reflect the change.
I think the error message is quite clear, the doc object means the whole document, according to your xpath, "doc.SelectSingleNode(xpath)" is not doc's child, it's descendant instead, so it throws the exception.
You can update the InnerText of the node, doc.OuterXml will reflect the change. The following code works fine for me:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'>" +
"<title>Pride And Prejudice</title>" +
"</book>");
string xPath = "/book/title";
XmlNode node = doc.SelectSingleNode(xPath);
node.InnerText = "new title";
Console.WriteLine(doc.OuterXml); //it's changed

How to add and delete an XML node?

I have this code below. I want to add a new node in it to hold more user records and if I want I can remove them. Can anyone help me?
string filename = "text.xml";
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("Login");
XmlElement id = doc.CreateElement("passWord");
root.SetAttribute("userName", nameTxb.Text);
id.SetAttribute("passWord", passwordTxb.Text);
XmlElement name = doc.CreateElement("UserName");
XmlElement passd = doc.CreateElement("PassWord");
name.InnerText = nameTxb.Text;
passd.InnerText = passwordTxb.Text;
root.AppendChild(name);
root.AppendChild(passd);
doc.AppendChild(root);
doc.Save(filename);
MessageBox.Show("Created SuccesFully!");
this.Close();
Your XML document is stored in variable doc. You may use doc.SelectNodes() to select specified nodes using XPATH. You may also iterate over selected nodes and append childs, remove childs etc.
var nodes = doc.SelectNodes("xpath");
foreach(XmlNode node in nodes)
{
//
}
This will remove an element. You can keep using SelectSingleNode() to move down through the branches of the xml. element can also be selected that way - for this example, just consider it an arbitrary starting point.
someElement.RemoveChild(oDoc.SelectSingleNode("Parent").SelectSingleNode("Child"));
As far as I know, you can also use the same method at the XmlDocument level too.
Hope this helps.

Categories