Replacing Whole XmlElement with new value - c#

I have got below code in which I am taking html and then reading all the img and a links. Note this is C# 2.0.
string xml = "<xhtml>" + inputXhtml + "</xhtml>";
XmlDocument node = new XmlDocument();
node.LoadXml(xml);
foreach (XmlElement element in TemplateUtilities.SelectNodes(node, "//html:img[#xlink:href]|//html:a[#xlink:href]"))
{
bool flag = element.LocalName == "img";
lStrCompLinkText = "";
XmlAttributeCollection attributes = element.Attributes;
XmlAttribute namedItem = (XmlAttribute)attributes.GetNamedItem("href", "http://www.w3.org/1999/xlink");
string str2 = namedItem.Value;
Component currentObject = engine.GetObject(str2) as Component;
if (flag)
{
element.SetAttribute("src", str2);
}
else
{
foreach (XmlNode xnode in element.ChildNodes)
{
lStrCompLinkText = lStrCompLinkText + xnode.OuterXml;
}
string attr = ComponentBase.ComponentHelper.ComponentLinkAttributes(element, engine);
string compLink = ComponentBase.ComponentHelper.DisplayPublishedComponentLink(currentObject, lStrCompLinkText, attr, engine, package, pageObject);
attributes.RemoveNamedItem("href", "http://www.tridion.com/ContentManager/5.0");
//Here I want to replace whole element with the compLink
}
attributes.RemoveNamedItem("href", "http://www.w3.org/1999/xlink");
attributes.RemoveNamedItem("type", "http://www.w3.org/1999/xlink");
attributes.RemoveNamedItem("title", "http://www.w3.org/1999/xlink");
}
Now I want to replcace my element with the new value compLink and add back to the input HTML
Please suggest

At the spot where your comment "// Here I want to replace" appears do the following.
Create an XML Document from the contentes of compLink (assuming it's XML).
XmlDocument xmlTemp = new XmlDocument();
xmlTemp.loadXml( compLink );
Remove the original element from it's parent with the following code
XmlNode ndParent = element.ParentNode;
ndParent.RemoveChild( element);
Import and append the new xmlTemp to the parent
XmlNode ndImport = ndParent.OwnerDocument.ImportNode( xmlTemp.documentElement, true );
ndParent.AppendChild( ndImport.CloneNode( true ) );

I solved my above problem using below logic:
XmlDocument lObjTCDCodeDom = new XmlDocument();
lObjTCDCodeDom.LoadXml("<TCDCode/>");
lObjTCDCodeDom.DocumentElement.InnerText = compLink;
element.ParentNode.ReplaceChild(node.ImportNode(lObjTCDCodeDom.DocumentElement, true), element);
and then further wrote the XSLT which check the <TCDCode/> and replaces it and then I get actual updated xml.

Related

How to get xml element values using XmlNodeList in c#

I need to store the element values which are inside the nodes "member" . I have tried the following code but I can't achieve it. How to get the values. Any help would be appreciated
XML:
<ListInventorySupplyResponse xmlns="http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/">
<ListInventorySupplyResult>
<InventorySupplyList>
<member>
<SellerSKU>043859634910</SellerSKU>
<FNSKU>X000IA4045</FNSKU>
<ASIN>B005YV4DJO</ASIN>
<Condition>NewItem</Condition>
<TotalSupplyQuantity>7</TotalSupplyQuantity>
<InStockSupplyQuantity>7</InStockSupplyQuantity>
<EarliestAvailability>
<TimepointType>Immediately</TimepointType>
</EarliestAvailability>
<SupplyDetail>
</SupplyDetail>
</member>
</InventorySupplyList>
</ListInventorySupplyResult>
<ResponseMetadata>
<RequestId>58c9f4f4-6f60-496a-8d71-8fe99ce301c9</RequestId>
</ResponseMetadata>
</ListInventorySupplyResponse>
C# Code:
string a = Convert.ToString(oInventorySupplyRes.ToXML());
XmlDocument oXdoc = new XmlDocument();
oXdoc.LoadXml(a);
XmlNodeList oInventorySupplyListxml = oXdoc.SelectNodes("//member");
foreach (XmlNode itmXml in oInventorySupplyListxml)
{
// var cond = itmXml.InnerXml.ToString();
var asinVal = itmXml.SelectSingleNode("ASIN").Value;
var TotalSupplyQuantityVal = itmXml.SelectSingleNode("TotalSupplyQuantity").Value;
}
ResultView : "Enumeration yielded no results" and count = 0;
Edit 1:
string a = Convert.ToString(oInventorySupplyRes.ToXML());
var status = oInventorySupplyResult.InventorySupplyList;
XmlDocument oXdoc = new XmlDocument();
var doc = XDocument.Parse(a);
var r = doc.Descendants("member")
.Select(member => new
{
ASIN = member.Element("ASIN").Value,
TotalSupplyQuantity = member.Element("TotalSupplyQuantity").Value
});
private string mStrXMLStk = Application.StartupPath + "\\Path.xml";
private System.Xml.XmlDocument mXDoc = new XmlDocument();
mXDoc.Load(mStrXMLStk);
XmlNode XNode = mXDoc.SelectSingleNode("/ListInventorySupplyResult/InventorySupplyList/member");
if (XNode != null)
{
int IntChildCount = XNode.ChildNodes.Count;
for (int IntI = 1; IntI <= IntChildCount ; IntI++)
{
string LocalName = XNode.ChildNodes[IntI].LocalName;
XmlNode Node = mXDoc.SelectSingleNode("/Response/" + LocalName);
// Store Value in Array assign value by "Node.InnerText"
}
}
Try This Code. Its Worked
try using this xpath
string xPath ="ListInventorySupplyResponse/ListInventorySupplyResult
/InventorySupplyList/member"
XmlNodeList oInventorySupplyListxml = oXdoc.SelectNodes(xpath);
when you do "//member", then, the code is trying to look for element named member from the root level, which is not present at the root level, rather it is nested beneath few layers.
I think this will help you..
string a = Convert.ToString(oInventorySupplyRes.ToXML());
XmlDocument oXdoc = new XmlDocument();
oXdoc.LoadXml(a);
XmlNodeList fromselectors;
XmlNodeList toselectors;
XmlElement root = oXdoc.DocumentElement;
fromselectors = root.SelectNodes("ListInventorySupplyResult/InventorySupplyList/member/ASIN");
toselectors = root.SelectNodes("ListInventorySupplyResult/InventorySupplyList/member/TotalSupplyQuantity");
foreach (XmlNode m in fromselectors)
{
you will have value in `m.InnerXml` use it whereever you want..
}
foreach (XmlNode n in toselectors)
{
you will have value in `n.InnerXml` use it whereever you want..
}

How to update the XMLDocument using c#?

I want to update the xml document and i need to return the updated xml in string. I am trying like below. when i save the document it expects the file name. but i dont want to save this as file. i just want to get the updated xml in string.
string OldXml = #"<Root>
<Childs>
<first>this is first</first>
<second>this is second </second>
</Childs
</Root>";
XmlDocument NewXml = new XmlDocument();
NewXml.LoadXml(OldXml );
XmlNode root = NewXml.DocumentElement;
XmlNodeList allnodes = root.SelectNodes("*");
foreach (XmlNode eachnode in allnodes)
{
if (eachnode.Name == "first")
{
eachnode.InnerText = "1";
}
}
NewXml.Save();
string newxml = NewXml.OuterXml;
You don't need to call Save method because string is immutable, your problem is in root.SelectNodes("*"), it just get child nodes, not all level of nodes. You need to go one more level:
foreach (XmlNode eachnode in allnodes)
{
var firstNode = eachnode.ChildNodes.Cast<XmlNode>()
.SingleOrDefault(node => node.Name == "first");
if (firstNode != null)
{
firstNode.InnerText = "1";
}
}
string newxml = NewXml.OuterXml;
It would be strongly recommended using LINQ to XML, it's simpler:
var xDoc = XDocument.Parse(OldXml);
foreach (var element in xDoc.Descendants("first"))
element.SetValue(1);
string newXml = xDoc.ToString();
Your iteration never reaches a node called "first". Else it would work fine without saving the NewXml.
You could however use a XElement and iterate over all descendants.
string OldXml = #"<Root>
<Childs>
<first>this is first</first>
<second>this is second </second>
</Childs>
</Root>";
var NewXml = XElement.Parse(OldXml);
foreach (var node in NewXml.Descendants())
{
if (node.Name.LocalName == "first")
{
node.Value = "1";
}
}
var reader = NewXml.CreateReader();
reader.MoveToContent();
string newxml = reader.ReadInnerXml();

How to insert xml data into existing xml in c#?

i added xml file in my windows application, i want to add values to that from textbox..
i used the following code,
string path = "codedata.xml";
XmlDocument doc = new XmlDocument();
if (!System.IO.File.Exists(path))
{
//Create neccessary nodes
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
XmlComment comment = doc.CreateComment("This is an XML Generated File");
doc.AppendChild(declaration);
doc.AppendChild(comment);
}
else //If there is already a file
{
// //Load the XML File
doc.Load(path);
}
//Get the root element
XmlElement root = doc.DocumentElement;
XmlElement Subroot = doc.CreateElement("data");
XmlElement Companycode = doc.CreateElement("Companycode");
XmlElement Productcode = doc.CreateElement("Productcode");
XmlElement Productname = doc.CreateElement("Productname");
XmlElement Brandcode = doc.CreateElement("Brandcode");
XmlElement Brandname = doc.CreateElement("Brandname");
Companycode.InnerText = txt_companycode.Text;
Productcode.InnerText = txt_productcode.Text;
Productname.InnerText = txt_productname.Text;
Brandcode.InnerText = txt_brandcode.Text;
Brandname.InnerText = txt_brandname.Text;
Subroot.AppendChild(Companycode);
Subroot.AppendChild(Productcode);
Subroot.AppendChild(Productname);
Subroot.AppendChild(Brandcode);
Subroot.AppendChild(Brandname);
root.AppendChild(Subroot);
doc.AppendChild(root);
//Save the document
doc.Save(path);
//Show confirmation message
MessageBox.Show("Details added Successfully");
it showing error near root.AppendChild(Subroot); can any one help me, wer i made mistake.
You can use Linq to XML, here is an example :
var xDoc = XElement.Load("FilePath");
if (xDoc == null)
return;
var myNewElement = new XElement("ElementName"
new XAttribute("AttributeName", value1),
new XAttribute("AttributeName", value2)
//And so on ...
);
xDoc.Add(myNewElement);
xDoc.Save("FilePath");
The root is null. Try to add Root element when you create XML file.
if (!System.IO.File.Exists(path))
{
//Create neccessary nodes
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
XmlComment comment = doc.CreateComment("This is an XML Generated File");
doc.AppendChild(declaration);
doc.AppendChild(comment);
doc.AppendChild(doc.CreateElement("Root"));
}
Or use LINQ-XML
string _file=#"c:\sample.xml";
XDocument doc;
if (!File.Exists(_file))
{
doc = new XDocument();
doc.Add(new XElement("Root"));
}
else
{
doc = XDocument.Load(_file);
}
doc.Root.Add(
new XElement("data",
new XElement("CompanyCode","C101"),
new XElement("ProductCode","P101")
)
);
doc.Save(_file);
In null XML DocumentElement is null. Try add Subroot to Document:
XmlElement root = doc.DocumentElement;
root.AppendChild(Subroot);
doc.AppendChild(root);
// new code
doc.AppendChild(Subroot);

Deleting XML using a selected Xpath and a for loop

I currently have the following code:
XPathNodeIterator theNodes = theNav.Select(theXPath.ToString());
while (theNodes.MoveNext())
{
//some attempts i though were close
//theNodes.RemoveChild(theNodes.Current.OuterXml);
//theNodes.Current.DeleteSelf();
}
I have set xpath to what I want to return in xml and I want to delete everything that is looped. I have tried a few ways of deleting the information but it does't like my syntax. I found an example on Microsoft support: http://support.microsoft.com/kb/317666 but I would like to use this while instead of a for each.
Any comments or questions are appreciated.
Why not to use XDocument?
var xmlText = "<Elements><Element1 /><Element2 /></Elements>";
var document = XDocument.Parse(xmlText);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
var result = document.ToString();
result will be <Elements><Element2 /></Elements>.
Or:
var document = XDocument.Load(fileName);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
document.Savel(fileName);
[Edit] For .NET 2, you can use XmlDocument:
XmlDocument document = new XmlDocument();
document.Load(fileName);
XmlNode node = document.SelectSingleNode("Elements/Element1");
node.ParentNode.RemoveChild(node);
document.Save(fileName);
[EDIT]
If you need to remove all child elements and attributes:
XmlNode node = document.SelectSingleNode("Elements");
node.RemoveAll();
If you need to keep attributes, but delete elements:
XmlNode node = document.SelectSingleNode("Elements");
foreach (XmlNode childNode in node.ChildNodes)
node.RemoveChild(childNode);
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);
XmlNode node = document.SelectSingleNode(nodeXPath);
node.RemoveAll();
XmlNode parentnode = node.ParentNode;
parentnode.RemoveChild(node);
document.Save("File Path");
You can use XmlDocument:
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);//or document.LoadXml(...
XmlNode node = document.SelectSingleNode(nodeXPath);
if (node.HasChildNodes)
{
//note that you can use node.RemoveAll(); it will remove all child nodes, but it will also remove all node' attributes.
for (int childNodeIndex = 0; childNodeIndex < node.ChildNodes.Count; childNodeIndex++)
{
node.RemoveChild(node.ChildNodes[childNodeIndex]);
}
}
document.Save("your file path"));

writing to xml attributes

Hey all i have code to write to an xml doc from asp
string filePath = Server.MapPath("../XML/MyXmlDoc.xml");
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(filePath);
}
catch (System.IO.FileNotFoundException)
{
//if file is not found, create a new xml file
XmlTextWriter xmlWriter = new XmlTextWriter(filePath, System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
string startElement = "markings";
xmlWriter.WriteStartElement(startElement);
xmlWriter.Close();
xmlDoc.Load(filePath);
}
XmlNode root = xmlDoc.DocumentElement;
XmlElement mainNode = xmlDoc.CreateElement("mark");
XmlElement childNode1 = xmlDoc.CreateElement("studentFirstName");
XmlElement childNode2 = xmlDoc.CreateElement("studentLastName");
XmlElement childNode3 = xmlDoc.CreateElement("className");
XmlElement childNode4 = xmlDoc.CreateElement("marks");
XmlText childTextNode1 = xmlDoc.CreateTextNode("");
XmlText childTextNode2 = xmlDoc.CreateTextNode("");
XmlText childTextNode3 = xmlDoc.CreateTextNode("");
XmlText childTextNode4 = xmlDoc.CreateTextNode("");
root.AppendChild(mainNode);
//this portion can be added to a foreach loop if you need to add multiple records
childTextNode1.Value = "John";
childTextNode2.Value = "Doe";
childTextNode3.Value = "Biology";
childTextNode4.Value = "99%";
mainNode.AppendChild(childNode1);
childNode1.AppendChild(childTextNode1);
mainNode.AppendChild(childNode2);
childNode2.AppendChild(childTextNode2);
mainNode.AppendChild(childNode3);
childNode3.AppendChild(childTextNode3);
mainNode.AppendChild(childNode4);
childNode4.AppendChild(childTextNode4);
//end of loop section
xmlDoc.Save(filePath);
which works fine but i want to store the xml in the following structure
graph
set name="John Doe" value="99";
/graph
instead of
name John Doe /name
value 99 /value
is there a way to store the xml like this? thanks all
You can add an attribute to your XmlElement by using the following syntax (C#) :
XmlAttribute value = xmlDoc.CreateAttribute("value");
childNode1.attributes.appendChild(value);
Hope this helps !
This code will do what you're looking for:
XmlElement graph = xmlDoc.CreateElement("graph");
XmlAttribute name = xmlDoc.CreateAttribute("name");
name.Value = "John Doe";
XmlAttribute value = xmlDoc.CreateAttribute("value");
value.Value = "99";
graph.SetAttributeNode(name);
graph.SetAttributeNode(value);
mainNode.AppendChild(graph);

Categories

Resources