Replace the field value in word document using Openxml - c#

I am developing an application in which I am accessing the word document xml from Microsoft Dynamics CRM and want to replace the fields which were added through XML Mapping pane.
Below is the XML which is retrieved through the OpenXML.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 wp14"><w:body><w:sdt><w:sdtPr><w:id w:val="1519887787"/><w:placeholder><w:docPart w:val="DefaultPlaceholder_1081868574"/></w:placeholder><w:dataBinding w:prefixMappings="xmlns:ns0='urn:microsoft-crm/document-template/new_candidate/10006/' " w:xpath="/ns0:DocumentTemplate[1]/new_candidate[1]/new_candidatename[1]" w:storeItemID="{2D909ED6-F428-47C5-93D4-89B5709D4B5C}"/><w:text/></w:sdtPr><w:sdtContent><w:p w:rsidR="0055490F" w:rsidRDefault="00F5486B"><w:r><w:t>new_candidatename</w:t></w:r></w:p></w:sdtContent></w:sdt><w:bookmarkStart w:id="0" w:name="_GoBack" w:displacedByCustomXml="prev"/><w:bookmarkEnd w:id="0" w:displacedByCustomXml="prev"/><w:sectPr w:rsidR="0055490F"><w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="1701" w:right="1134" w:bottom="1701" w:left="1134" w:header="708" w:footer="708" w:gutter="0"/><w:cols w:space="708"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>
In the above XML, there is one field called new_candidatename, which I want to replace with my custom value.
Can anyone please suggest me how do I replace the value using OpenXML?

If you are using c# there is no reason to use openxml. You can use xml linq library.
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);
XElement t = doc.Descendants().Where(x => x.Name.LocalName == "t").FirstOrDefault();
t.Value = "New Value";
doc.Save(FILENAME);
}
}
}

Related

Altering string variable storing xml in c#

string content = ....
I have some XML content stored in a string as shown in the variable above. The content stored is similar to below ,
<?xml version="1.0"?>
<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<ItemModel xsi:type="TypeKeep">
<Name>Name01</Name>
</ItemModel>
<ItemModel xsi:type="TypeDelete">
<Name>Name02</Name>
</ItemModel>
<ItemModel xsi:type="TypeDelete">
<Name>Name03</Name>
</ItemModel>
</Items>
</model>
In here I want to remove all the elements which have the type="TypeDelete" . In the sense I am trying to alter the content variable by removing the elments of TypeDelete
Any idea how I can achieve this ?
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(xml);
XNamespace xsiNs = doc.Root.GetNamespaceOfPrefix("xsi");
List<XElement> removeNodes = doc.Descendants("ItemModel").Where(x => (string)x.Attribute(xsiNs + "type") == "TypeDelete").ToList();
for (int i = removeNodes.Count - 1; i >= 0; i--)
{
removeNodes[i].Remove();
}
}
}
}
If you want to remove a specific XML node from an XML file directly you can go through this link and try this

How to write CData of XML which contain inner nodes in C#?

I have following xml document
<Node id="1" name="name1" autoplayTrailer="false" visible="true" bgimages="false">
<Text>
<title id="2" type="text" hideineditor="false" visible="true"><![CDATA[Link]]></title>
<sections id="3" default="consideration">
<songs id="4" type="text" hideineditor="false" enabled="true" visible="true">
<![CDATA[
<div class="ThumbContainer">
Some text here
</div>
]]>
<songsTitle><![CDATA[sometexthtml here]]></songsTitle>
</songs>
</sections>
</Text>
</Node>
I want to read the content/node one by one and modify the CDATA content and write the xml to disc.
Problem is i am not able to write the CData for <songs> node becoz it has another node inside <songTitle> node without closing the </song> node is it possilbe to write node with CData having another node following CData content?
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);
foreach (XElement node in doc.Descendants("Node"))
{
XElement songs = node.Descendants("songs").FirstOrDefault();
XCData child = (XCData)songs.FirstNode;
string childStr = child.ToString();
childStr = childStr.Replace("Some text here", "Some text there");
child.ReplaceWith(childStr);
}
}
}
}
Is this the output you want to create?
This example outputs the CData & 'other element' under the 'songs' element using the XmlTextWriter API.
using System;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace WriteCData
{
class Program
{
static void Main(string[] args)
{
// some output to write to
XmlTextWriter xtw = new XmlTextWriter(#"c:\temp\CDataTest.xml", null);
// start at 'songs' element
xtw.WriteStartElement("songs");
xtw.WriteCData("<div class='ThumbContainer'>Some text here</div>");
xtw.WriteStartElement("songsTitle");
xtw.WriteCData("sometexthtml here");
xtw.WriteEndElement(); // end "songTitle"
xtw.WriteEndElement(); // end "songs"
xtw.Flush(); // clean up
xtw.Close();
}
}
}
output:
<songs>
<![CDATA[<div class='ThumbContainer'>Some text here</div>]]>
<songsTitle><![CDATA[sometexthtml here]]></songsTitle>
</songs>
The idea is to replace the static text used in the example with the values you read from your source document you mention in your question.

Modifying two fields in .XML file

I have a XML file which looks like:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<UFCC xmlns="http://actel.com/sweng/afi">
<Region name="Region_0_0">
<content>
<static_data>
<fixed>
<value>11111111111111111111111111111111</value>
<type>HEX</type>
</fixed>
</static_data>
</content>
<region_start_word>0</region_start_word>
<number_of_word>16</number_of_word>
<simulation_value>
<value>11111111111111111111111111111111</value>
<type>HEX</type>
</simulation_value>
</Region>
<Region name="Region_1_0">
<content>
<static_data>
<fixed>
<value>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</value>
<type>HEX</type>
</fixed>
</static_data>
</content>
<region_start_word>16</region_start_word>
<number_of_word>16</number_of_word>
<simulation_value>
<value>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</value>
<type>HEX</type>
</simulation_value>
</Region>
<Program_Pages/>
</UFCC>
I'm trying to change value fields "11111111111111111111111111111111" to "A...A". I have tried this with Xml.Linq and using examples found online, from which none seem to work.
How can I modify these fields?
Sorry about the formatting, I'm not that familiar with proper XML formatting and the source file is written in single line.
You need to use the namespace :
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);
XElement root = doc.Root;
XNamespace ns = root.GetDefaultNamespace();
List<XElement> values1s = doc.Descendants(ns + "value").Where(x => (string)x == "11111111111111111111111111111111").ToList();
foreach (XElement x in values1s)
{
x.SetValue(((string)x).Replace("1", "A"));
}
}
}
}

How can I create a webapi with nested xml from ssms table?

I have made a web api with C# and an ssms table. The result is an xml with only elements.
//This is only an example
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
How can I format my xml as nested like this and add an optional different header from ssms table element??:
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<example>
<from>Jani
<heading>Reminder</heading>
</from>
<body>Don't forget me this weekend!</body>
</example>
</note>
Use xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication78
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<note>" +
"<to>Tove</to>" +
"<from>Jani</from>" +
"<heading>Reminder</heading>" +
"<body>Don't forget me this weekend!</body>" +
"</note>";
XDocument doc = XDocument.Parse(xml);
XElement from = doc.Descendants("from").FirstOrDefault();
XElement heading = doc.Descendants("heading").FirstOrDefault();
XElement body = doc.Descendants("body").FirstOrDefault();
from.Add(heading);
XElement example = new XElement("example", new object[] {from,body});
heading.Remove();
body.Remove();
from.ReplaceWith(example);
}
}
}
If you are creating from scratch
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication78
{
class Program
{
static void Main(string[] args)
{
string ident = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><note></note>";
XDocument doc = XDocument.Parse(ident);
XElement note = doc.Root;
note.Add(new XElement("to", "Tove"),
new XElement("example", new object[] {
new XElement("from", new object[] {
"Jani", new XElement("heading", "Reminder")
}),
new XElement("body","Don't forget me this weekend!")
})
);
}
}
}

How to get the version number from a given XSLT file .

Say I have an XSLT file like below:
`<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-
prefixes="xs math"
version="3.0">`
....... and so on.
I need the output as 3.0 because the above file has version="3.0". I want to use C# to get this given the XSLT is in string format
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)
{
XDocument doc = XDocument.Load(FILENAME);
string version = (string)doc.Root.Attribute("version");
}
}
}
Use XElement.Parse(yourString).Attribute("version").Value, where you add using System.Xml.Linq;. See https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/linq-to-xml-overview for details of the used API.

Categories