I have two XML files that I want to merge in first file’s nodes
First file
Toc.xml
<toc>
<item id ="c12">
<english>book1</english>
<french>book1</french>
</title>
</item>
<item id = "part1"/>
<item id = "part2"/>
<item id = "part3"/>
</toc>
Second file will be updated every time after running transformation with XML files(part 1,2,3)
Second file :while running transformation with part1.xml
<item id = “part 1”>
<title>
<english>part1</english>
<french>part1</french>
</title></item>
Second file :while running transformation with part2.xml
<item id = “part 2”>
<title>
<english>part2</english>
<french>part2</french>
</title>
</item>
Result in Toc file
<toc>
<item id ="c12">
<english>book1</english>
<french>book1</french>
</title>
</item>
<item id = "part1">
<title>
<english>part1</english>
<french>part1</french>
</title>
</item>
<item id = "part2">
<title>
<english>part2</english>
<french>part2</french>
</title>
</item>
<item id = "part3">
<title>
<english>part3</english>
<french>part3</french>
</title>
</item>
</toc>
I tried using import node but it gives me errors(root element is missing) and other error "The node to be inserted is from a different document context"
Here is the code i tried
XmlDocument temp = new XmlDocument();
temp.Load("secondfile.xml");
XmlDocument toc = new XmlDocument();
toc.Load(toc.xml);
XmlNodeList toclist = toc.SelectNodes("/toc/item");
foreach (XmlNode tocnode in toclist)
{XmlNodeList tempnodelist = temp.SelectNodes("/item");
foreach (XmlNode tempnode in tempnodelist)
{ XmlNode importnode = toc.ImportNode(tempnode, true);
toc.appendNode(importnode, tocnode);
}}
you are right. My question was not clear. i changed que to be more specific. i hope you will find it more clean this time.
Thank you.
<item id = “part 1”>
<title>
<english>part1</english>
<french>part1</french>
</title>
</item>
<toc>
<item id ="c12">
<english>book1</english>
<french>book1</french>
</item>
<item id = "part1"/>
<item id = "part2"/>
<item id = "part3"/>
</toc>
The answer might be:
XmlDocument mainDocument = new XmlDocument();
mainDocument.Load("toc.xml");
XmlDocument tempDocument = new XmlDocument();
tempDocument.Load("part1.xml");
XmlNodeList tempList = tempDocument.GetElementsByTagName("item");
string id=tempList[0].GetAttribute("id");//gets the id attribute value
XmlNode mainRoot = mainDocument.DocumentElement; //gets the root node of the main document toc.xml
XmlNodeList mainList = mainRoot.SelectNodes("/toc");
XmlNode itemNode = mainList.Item(0).SelectSingleNode(string.Format("/toc/item[#id=\"" + id + "\"]")); //select the item node according to the id attribute value
XmlNode tempitemNode = tempList.Item(0).SelectSingleNode(string.Format("/toc/item[#id=\"" + id + "\"]/title")); //select the title node of the part1, part2 or part3 files
itemNode.AppendChild(tempitemNode.FirstChild);
itemNode.AppendChild(tempitemNode.LastChild);
mainDocument.Save("toc.xml");
Something like that
Related
I'm trying to insert an xml node with another child xml node in an existing xmldocument in C#.
I've got an XML doc that looks like so:
<?xml version="1.0" encoding="utf-16"?>
<DictionarySerializer>
<item>
<key>statusCode</key>
<value>0</value>
</item>
<item>
<key>statusSeverity</key>
<value>INFO</value>
</item>
<item>
<key>statusMessage</key>
<value>Status OK</value>
</item>
<item>
<key>MerchantAccountNumber</key>
<value>9999999999</value>
</item>
<item>
<key>ReconBatchID</key>
<value>420150418 1Q02144266965047801046AUTO04</value>
</item>
<item>
<key>PaymentGroupingCode</key>
<value>3</value>
</item>
<item>
<key>responsePaymentStatus</key>
<value>Completed</value>
</item>
<item>
<key>TxnAuthorizationTime</key>
<value>2015-04-18T09:14:41</value>
</item>
<item>
<key>TxnAuthorizationStamp</key>
<value>1429348481</value>
</item>
<item>
<key>ClientTransID</key>
<value>aidjl79f</value>
</item>
</DictionarySerializer>
and I need to insert another node with a node and node at the bottom.
I have this so far:
XmlDocument xmlCustomValues = new XmlDocument();
xmlCustomValues.LoadXml(OldCustomValues);
XmlNode NodeItem = xmlCustomValues.SelectSingleNode("DictionarySerializer");
XmlNode NodeNewItem = xmlCustomValues.CreateNode(XmlNodeType.Element, "item", null);
XmlNode NodeNewKey = NodeNewItem.??????
but not sure how to create a node under NodeNewItem (there's no "CreateNode" method). Never done this before (obviously) and the syntax does not make sense to me.
here's an answer that worked (test code for XML doc above)
string OldCustomValues = this.txtInput.Text;
XmlDocument xmlCustomValues = new XmlDocument();
xmlCustomValues.LoadXml(OldCustomValues);
XmlNode NodeItem = xmlCustomValues.SelectSingleNode("DictionarySerializer");
XmlNode NodeNewItem = xmlCustomValues.CreateNode(XmlNodeType.Element, "item", null);
NodeItem.AppendChild(NodeNewItem);
XmlNode NodeNewKey = xmlCustomValues.CreateNode(XmlNodeType.Element, "key", null);
NodeNewKey.InnerText = "MyKey";
XmlNode NodeNewValue = xmlCustomValues.CreateNode(XmlNodeType.Element, "value", null);
NodeNewValue.InnerText = "MyValue";
NodeNewItem.AppendChild(NodeNewKey);
NodeNewItem.AppendChild(NodeNewValue);
this.txtOutput.Text = xmlCustomValues.OuterXml;
You have already created the node, u just need to append the node to the root
NodeItem.AppendChild(NodeNewItem);
I have 1000 records in text file. My requirement is to insert data into SQL Server. For that, if I can convert to XML or push to script component also fine.
Source Text file consists in this format...
[{"ID":1,"Name":"test1","State":"AP"},{"ID":2,"Name":"test2","State":"KN"},{"ID":3,"Name":"test3","State":null}]
String json = System.IO.File.ReadAllText(#"C:\t1.txt");
byte[] bytes = Encoding.ASCII.GetBytes();
using (var stream = new MemoryStream(bytes))
{
var quotas = new XmlDictionaryReaderQuotas();
var jasonreader - JsonReaderWriterFactory.CreateJasonReader(stream,quotas);
var xml = XDocument.Load(jsonreader);
xmlDocument xd = new XmlDocument();
using (steamwriter fs = new streamwriter(#"C:\t.xml");
{
fs.write(xml);
}
console.writeLine(xml);
}
Output -
<root type="array"
<item type="object">
<ID type="number">1</ID>
<Name type="string">test1</Name>
<State type="string">AP</State>
</item>
<item type="object">
<root type="array"
<item type="object">
<ID type="number">2</ID>
<Name type="string">test2</Name>
<State type="string">KN</State>
</item>
<item type="object">
<root type="array"
<item type="object">
<ID type="number">3</ID>
<Name type="string">test3</Name>
<State type="string"></State>
</item>
</root>
When am using SSIS XML Source task, am getting columns...
External Columns:
type
text
item_id
Output Columns:
type
text
item_id
Ideally, I should get ID, Name, and State columns. What is the issue? How can I get rid of type in XML?
How about using Linq? (using Json.Net)
var jArr = JArray.Parse(File.ReadAllText(filename));
XElement root = new XElement("root");
foreach(JObject jObj in jArr )
{
root.Add(new XElement("item", jObj.Properties()
.Select(p => new XElement(p.Name,
p.Value.ToString()))
.ToArray()));
}
var xml = root.ToString();
or using more linq
var jArr = JArray.Parse(File.ReadAllText(filename));
XElement root = new XElement("root");
root.Add( jArr.Cast<JObject>()
.Select(jObj => new XElement("item", jObj.Properties()
.Select(p => new XElement(p.Name,
p.Value.ToString()))
.ToArray())));
var xml = root.ToString();
I am creating application to make Mod Menu's for Modern Warfare 3 (XRPC). I am making it customisable with XML, i have created an Example XML.
<MenuFile>
<Credits>
<Author>Callum Carmicheal</Author>
<Name>Sample</Name>
<Version>0.1</Version>
</Credits>
<InfoBar>
<Text>Created by ..., Enjoy</Text>
</InfoBar>
<Menu>
<Main>
<Header>
<Name>Main Menu</Name>
</Header>
<Item>
<Name>Enable Cheats</Name>
<Function>
<Menu>Mods</Menu>
</Function>
<Ignore>false</Ignore>
</Item>
<Item>
<Name> </Name>
<Function> </Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
</Main>
<Mods>
<Header>
<Name>Mods</Name>
</Header>
<Item>
<Name>Enable Cheats</Name>
<Function>
<Dvar>sv_cheats 1</Dvar>
</Function>
<Ignore>false</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
<Item>
<Name></Name>
<Function></Function>
<Ignore>True</Ignore>
</Item>
</Mods>
</Menu>
</MenuFile>
This is the markup for the Menu's, i have created some c# Code
private void button1_Click(object sender, EventArgs e) {
XmlDocument xml = new XmlDocument();
xml.LoadXml(System.IO.File.ReadAllText("menu.xml")); // suppose that myXmlString contains "<Names>...</Names>"
XmlNode credits_author = xml.SelectSingleNode("/MenuFile/Credits/Author");
XmlNode credits_name = xml.SelectSingleNode("/MenuFile/Credits/Name");
XmlNode credits_version = xml.SelectSingleNode("/MenuFile/Credits/Version");
Log("Credits(Author): " + credits_author.InnerText);
Log("Credits(Name): " + credits_name.InnerText);
Log("Credits(Version): " + credits_version.InnerText);
XmlNode InfoBar = xml.SelectSingleNode("/MenuFile/InfoBar/Text");
Log("");
Log("InfoBar Text: " + InfoBar.InnerText);
Log("");
Log("Menus");
XmlNodeList Menus = xml.SelectNodes("/MenuFile/Menu");
// This returns
// /MenuFile/Menu not /MenuFile/Menu/MainMenu....
// it should loop through MainMenu, Mods...
foreach (XmlNode MenuItem in Menus) {
Log("\t Menu: " + MenuItem.Name); // Main should me MainMenu or Mods
XmlNodeList Items = xml.SelectNodes("/MenuFile/Menu/" + MenuItem.Name);
foreach (XmlNode mi in Items) {
if (mi.Name == "Header") {
string xpath = FindXPath(mi);
string Header = xml.SelectSingleNode("/MenuFile/Menu/" + MenuItem.Name + "/Header/Name").InnerText;
Log("\t\t Header: " + Header);
}
else if (mi.Name == "Item") {
string Name = "";
string ignore = "";
}
}
}
}
But the problem is when trying to retrieve the MenuList/Menu's children nodes, it returns MenuList/Menu itself i have no clue.
I've tried debugging but the results are the same, can anyone see my error in this?
Your problem is that you are looping through the Menu nodes, not Main or Mods nodes:
XmlNodeList Menus = xml.SelectNodes("/MenuFile/Menu");
foreach (XmlNode MenuItem in Menus) {
will always return the outer Menu nodes.
To fetch the Main/Mods nodes use the following:
XmlNodeList menus = xml.SelectNodes("/MenuFile/Menu/*");
foreach (XmlNode menuItem in menus) {
Also, rather just fetch 'Header' and 'Items' nodes directly rather than performing an unnecessary "if":
XmlNode headerItem = menuItem.SelectSingleNode("Header");
...
XmlNodeList items = menuItem.SelectNodes("Item");
foreach (XmlNode item in items) {
...
Given the following XML:
<Root>
<Item id="1">
<name>Foo</name>
<status>Active</status>
</Item>
<Item id="2">
<name>Bar</name>
<status>Inactive</status>
</Item>
</Root>
Let's say I have this XML in an XmlDocument object and then have the following code:
var nodes = xmlDocumentObject.GetElementsByTagName("Item");
foreach (var node in nodes)
{
var nodeXml = ??
}
I can easily get the InnerXml of each node, which for the first node would be:
<name>Foo</name>
<status>Active</status>
But how can I get the XML for the node including the containing tag and its attributes, such as this:
<Item id="1">
<name>Foo</name>
<status>Active</status>
</Item>
Try using XmlNode.OuterXml instead of InnerXml :
foreach (XmlNode node in nodes)
{
var nodeXml = node.OuterXml;
}
I'm trying to get an element and its siblings via XpathNavigator.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE document SYSTEM 'xmlschemas/domino_6_5_5.dtd'>
<document xmlns='http://www.lotus.com/dxl' version='6.5' maintenanceversion='5.0'>
<item name='Keywords'><text/></item>
<item name='Version'><number>1</number></item>
<item name='UPDATEDISTRIBUTION'><text>1</text></item>
<item name='$FILE' summary='true' sign='true' seal='true'>
<object>
<file hosttype='cdstorage' compression='none' flags='storedindoc' name='STG08828'>
<created><datetime>20110119T230442,22+01</datetime></created>
</file>
</object>
</item>
</document>
I want to navigate to the file-element, with the following XPath:
//item/name/object/file[#name='STG08828']
Why this path is wrong?
EDIT: Thanks for the hint with my "name"-mistake.
When I try to run it, I get nothing.
XmlElement rootNode = xmlDoc.DocumentElement;
// select the file Element
String query = "//file[#name='" + name + "']";
XmlNodeList fileElement = rootNode.SelectNodes(query);
I think you want:
//item/object/file[#name='STG08828']
Or maybe just:
//file[#name='STG08828']
I think you are missing your names space for xmlns='http://www.lotus.com/dxl'
Example:
XNamespace myMs = "http://www.lotus.com/dxl";