As a follow up to this question I cannot figure out how to remove a period from all of my field names in JSON input.
I am converting XML to JSON and creating a BsonDocument to be inserted into a MongoDB database using the Newtonsoft library like this:
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
String jsonText = JsonConvert.SerializeXmlNode(doc);
BsonDocument = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(jsonText);
I can't insert this because I'll get a serialization exception since the element name contains a period. How can I process through either the JSON string or the BsonDocument to change them?
I have successfully iterated through my document recursively:
private void Print(BsonDocument document)
{
foreach (BsonElement element in document)
{
Console.WriteLine(element.Name);
if (element.Value.IsBsonDocument)
{
Print(element.Value.AsBsonDocument);
}
else if (element.Value.IsBsonArray)
{
var array = element.Value.AsBsonArray;
foreach (BsonDocument doc in array)
{
Print(doc);
}
}
}
}
However, BsonDocument.Name is not a field I can set, only get. How can I update the BsonDocument or the JSON string to remove the invalid field names?
I dont know enough about your XML/JSON structure but why dont you process the XML before you convert it into JSON and replace the ElementNames? As outlined in this ANSWER?
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(File.ReadAllText(#"{path}\xml.xml", Encoding.Default));
XmlNodeList nodeList = xmlDoc.SelectNodes("//*['.' = substring(name(), string-length(name())- string-length('.') +1)]");
foreach (XmlNode node in nodeList)
{
string newName = node.Name.Replace(".", "");
// create new (renamed) Content node
XmlNode newNode = xmlDoc.CreateElement(newName);
newNode.InnerXml = node.InnerXml;
// replace existing BatteryTest node with newly renamed Content node
node.ParentNode.InsertBefore(newNode, node);
node.ParentNode.RemoveChild(node);
}
xmlDoc.Save(#"{path}\xml.xml");
Related
I am work on some innerxml of an XML document.
I have to concat several parts.
I have this:
<TRANFSERT><GOOD></GOOD></TRANSFERT>
I want to insert another part, <GOOD></GOOD>, before </TRANSFERT>.
I tried this:
int pos = xmldoc.indexOf("</GOOD>");
StringBuilder sb = new StringBuilder(xmlFinal);
sb.Append(xmlModifiee,pos,xmlModifiee.length);
xmlFinal = sb.ToString();
But it doesn't work.
How can I add a small part of XML in other XML?
You shouldn't interact with XML like with ordinary string.
Use provided System.Xml.XmlDocument or System.Xml.Linq.XDocument classes:
Ordinary XmlDocument single node selection and appending new element to it:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("YourFile.xml");
XmlNode goodNode = xmlDocument.SelectSingleNode("TRANSFERT/GOOD");
XmlNode nodeToInsert = xmlDocument.CreateElement("INSERTEDNODE");
goodNode.AppendChild(nodeToInsert);
Ordinary XmlDocument iterating by nodes to find necessary (be aware for many-childed nodes) and add new child node to it:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("YourFile.xml");
foreach (XmlNode rootNode in xmlDocument.ChildNodes)
{
if (rootNode.Name == "TRANSFERT")
{
foreach (XmlNode childNode in rootNode.ChildNodes)
{
if (childNode.Name == "GOOD")
{
XmlNode nodeToInsert = xmlDocument.CreateElement("INSERTEDNODE");
childNode.AppendChild(nodeToInsert);
}
}
}
}
Linq to XML variant:
XDocument xDoc = XDocument.Load("YourFIle.xml");
XElement rootElement = xDoc.Element("TRANSFERT");
XElement goodElement = rootElement.Element("GOOD");
goodElement.Add(new XElement("INSERTEDNODE"));
Simplified Linq to XML variant:
XDocument.Load("YourFIle.xml").Element("TRANSFERT").Element("GOOD").Add(new XElement("INSERTEDNODE"));
EDITED: answering the question, example was rewrited from changing InnerText values to Append/Add new child element to GOOD node.
StringBuilder.Append can only be used to add something to the end of the string. To add something inside the string, use StringBuilder.Insert like this:
sb.Insert(pos, xmlModifiee);
I have a xml like this:
<xmlRootNode>
<levelOneChildNode>
Some text
<levelTwoChildNode>
<levelThreeChildNode>More text</levelThreeChildNode>
</levelTwoChildNode>
</levelOneChildNode>
</xmlRootNode>
I can't change the xml format because my client wants this format. How I should create and decorate "levelOneChildNode" class for a correct serialization? I can't use XmlElement or XmlAttribute. The only way to do this than I've thought is put "Some text" as a XmlElement and make a
string.replace("<textNode>", string.empty).replace("</textNode>", string.empty)
with de serialized xml to remove de tag but this is a crapy solution.
Any ideas without manual xml manipulation?
I guess you have two options, both of them related to manual xml-manipulation:
Use
XmlWriter
to write elements one by one.
Fill general-purpose
XmlDocument,
and save it.
Set/Retrieve/Append/Create XmlNotes (values):
//file name
string filename = #"d:\temp\XMLFile2.xml";
//create new instance of XmlDocument
XmlDocument _doc = new XmlDocument();
//load from file
_doc.Load(filename);
// Change text in xml
XmlNode node= _doc.SelectSingleNode("xmlRootNode/levelOneChildNode"); // [index of user node]
node.InnerText = value;
_doc.Save(#"path");
// Retrive value from xml
XmlNode node = _doc.SelectSingleNode("xmlRootNode/levelOneChildNode/levelTwoChildNode/someAttribute");
string value = node.InnerText;
// read or write to more elements
foreach (XmlNode node in doc.SelectNodes("xmlRootNode/levelOneChildNode/levelTwoChildNode"))
{
string data= node.SelectSingleNode("someAttribute").InnerTex; // get value of someAttribute.
node.InnerText = value;
}
// Append Note to levelOneChildNode Note
// Create second node
XmlNode secondNode = doc.CreateElement("SecondLevelNode");
secondNode .InnerText = "This title is created by code"
XmlNode firstNode= _doc.SelectSingleNode("xmlRootNode/levelOneChildNode");
firstNode.AppendChild(secondNode );
_doc.Save(#"path");
I got this function for simply get the inner text of my xml:
XmlDocument document = new XmlDocument();
document.Load("game.xml");
string content = document.SelectSingleNode("Game/Client-Version").InnerText;
(this is the xml file (due to complications with stackoverflow posted on pastebin)): http://pastebin.com/EEeFAJpC
And now I am exactly looking for the function above, just to write. Like
document.WriteSingleNode("Game/Client-Version", "texttowrite");
I did not find anything helping me out.
This should work
XmlElement x = document.SelectSingleNode("Game/Client-Version") as XmlElement;
x.InnerText = "texttowrite";
Create your own extension method:
public void WriteSingleNode(this XmlDocument document, string NodeName, string InnerText)
{
// Create a new element node.
XmlNode newElem = document.CreateNode("element", "pages", "");
newElem.InnerText = InnerText;
Console.WriteLine("Add the new element to the document...");
document.DocumentElement.AppendChild(newElem);
Console.WriteLine("Display the modified XML document...");
Console.WriteLine(document.OuterXml);
}
I have an XML File like below
<Attachment>
<FileName>Perimeter SRS.docx</FileName>
<FileSize>15572</FileSize>
<ActivityName>ActivityNamePerimeter SRS.docx</ActivityName>
<UserAlias>JameelM</UserAlias>
<DocumentTransferId>7123eb83-d768-4a58-be46-0dfaf1297b97</DocumentTransferId>
<EngagementName>EAuditEngagementNameNew</EngagementName>
<Sender>JameelM#orioninc.com</Sender>
</Attachment>
I read these xml file like below
var doc = new XmlDocument();
doc.Load(files);
foreach (XmlElement pointCoord in doc.SelectNodes("/Attachment"))
{
}
I need to get each child node value inside the Attachment node. How can i get these xml elements from the xml node list?
I need to get each child node value inside the Attachment node.
Your question is very unclear, but it looks like it's as simple as:
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
{
}
After all, in the document you've shown us, the Attachment is the document element. No XPath is required.
As an aside, if you're using .NET 3.5 or higher, LINQ to XML is a much nicer XML API than the old DOM (XmlDocument etc) API.
try this
var data = from item in doc.Descendants("Attachment")
select new
{
FileName= item.Element("FileName").Value,
FileSize= item.Element("FileSize").Value,
Sender= item.Element("Sender").Value
};
foreach (var p in data)
Console.WriteLine(p.ToString());
var doc = new XmlDocument();
doc.Load(files);
foreach (XmlElement pointCoord in doc.SelectNodes("/Attachment"))
{
if(pointCoord!=null)
{
var valueOfElement=pointCoord.InnerText;
}
}
if you want to run conditional logic against the element names (UserAlias, etc) then use the Name property of the XmlElement.
How can i modify the value of an attribute within an xml loaded using Loadxml()?
I'm trying to update the xml string stored in my db. For that, i used the following code:
XmlDocument doc = new XmlDocument();
doc.LoadXml(project.ProjectData);
XmlNodeList pNodes = doc.SelectNodes("project");
foreach (XmlNode pNode in pNodes)
{
XmlAttribute lPDAttribute = pNode.Attributes["lastPubDate"];
if (lPDAttribute != null)
{
string currentValue = lPDAttribute.Value;
if (string.IsNullOrEmpty(currentValue))
{
lPDAttribute.Value = project.PublishDate.ToString();
}
}
}
What should i do to save the updated attribute within my current xml? Please help.
I think you should add the below code line
project.ProjectData = doc.InnerXml
you can store doc.InnerXml as a string in your db