none
To replace custom XML from the dotx file using Open XML SDK 2.0. RRS feed

  • Question

  • Hi,
    I am trying to replace the XML tags from the .dotx file with the corresponding value form the XML file. I am using MS .NET Framework version 3.5.
    I have followed below steps:-
    1. Created one .XSD file(XML Schema File).

    <?xml version="1.0" standalone="yes"?>
    <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="en-US">
    <xs:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="Table">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="PROFILE_ID" msdata:AutoIncrement="true" type="xs:int" />
    <xs:element name="PROFILE_NAME" minOccurs="0">
    <xs:simpleType>
    <xs:restriction base="xs:string">
    <xs:maxLength value="65536" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    <xs:element name="CREATION_DATE" minOccurs="0">
    <xs:simpleType>
    <xs:restriction base="xs:string">
    <xs:maxLength value="65536" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    <xs:element name="SRC_REP_ID" type="xs:int" minOccurs="0" />
    <xs:element name="TARGET_REP_ID" type="xs:int" minOccurs="0" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1" msdata:PrimaryKey="true">
    <xs:selector xpath=".//Table" />
    <xs:field xpath="PROFILE_ID" />
    </xs:unique>
    </xs:element>
    </xs:schema>


    2. Created one .XML file.
    <?xml version="1.0" standalone="yes"?>
    <NewDataSet>
      <Table>
        <PROFILE_ID>136</PROFILE_ID>
        <PROFILE_NAME>P8TOP8</PROFILE_NAME>
        <CREATION_DATE>9/30/2009 9:35:26 AM</CREATION_DATE>
        <SRC_REP_ID>10</SRC_REP_ID>
        <TARGET_REP_ID>1</TARGET_REP_ID>
      </Table>
    </NewDataSet>
    3. Created one .dotx file using schema(.xsd) in the .doc file. After adding schema added XML tags from the XML sructure in the doc file and saving the file.

    4. Used the following code  to replace the XML tags form the .dotx file to the correspong value from the XML file:-

    string

    sFileName = @"d:\ucm\test.dotx";
    string sSourceXML = @"d:\ucm\test.xml";
    using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(sFileName, true))
    {
    MainDocumentPart abc = wdDoc.MainDocumentPart;
    }
    using (Package package = Package.Open(sFileName, FileMode.Open, FileAccess.ReadWrite))
    {
    Uri uriPartTarget = new Uri("/customXml/item1.xml", UriKind.Relative);
    package.DeletePart(uriPartTarget);
    // Recreate a new document part
    PackagePart packagePartReplacement = package.CreatePart(uriPartTarget, "application/vnd.openxmlformats-officedocument.customXmlProperties+xml");
    using (FileStream fileStream = new FileStream(sSourceXML, FileMode.Open, FileAccess.Read))
    {
    // Load the new custom.xml using a stream.
    CopyStream(fileStream, packagePartReplacement.GetStream());
    }
    }
    }
    private static void CopyStream(Stream source, Stream target)
    {
    const int bufSize = 0x1000;
    byte[] buf = new byte[bufSize];
    int bytesRead = 0;
    while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
    {
    target.Write(buf, 0, (
    int)bytesRead);
    }
    source.Close();
    target.Close();
    }

    Code is executing succesfully with out any error, but it is not updating the XML tags in the dotx file from the corresponding values in the .XML file.
    Pleas help me if i am missing some where.
    Monday, November 16, 2009 9:50 AM

All replies

  • I don't understand why you are opening the same file "sFileName" using both WordprocessingDocument.Open and Package.Open. Only one of these is needed, ideally WordprocessingDocument.Open, since the SDK extends System.IO.Packaging.

    This appears to be a mail-merge type application. If so, I recommend reading the following article, which describes step-by-step how to create such an application:

    http://openxmldeveloper.org/articles/7708.aspx

    Wednesday, November 18, 2009 9:42 AM
  • Thanks for your response.
    Our requirement is different form thh mail-merge type. I need to replace the custom XML in the word document with corresponding value from the XML document.


    I am not clear what below part of code is doing.
    1. What does this file "/customXml/item1.xml" contains.
    Uri uriPartTarget = new Uri("/customXml/item1.xml", UriKind.Relative);

    2. What we are deleteing from package.
    package.DeletePart(uriPartTarget);


    3. what we adding to the package.
    // Recreate a new document part

    PackagPart packagePartReplacement = package.CreatePart(uriPartTarget, "application/vnd.openxmlformats-officedocument.customXmlProperties+xml"
    );

    Please provide me some help.
    Thursday, November 19, 2009 7:49 AM
  • Here's an article that talks about working with custom xml:

    http://blogs.msdn.com/dmahugh/archive/2006/06/16/633130.aspx

    Another good source of information is the eBook OpenXML Explained (see page 35 for custom xml), by Wouter Van Vugt:

    http://openxmldeveloper.org/attachment/1970.ashx

    However, to make life easier for yourself, I strongly recommend that you move away from System.IO.Packaging and work directly with the WordprocessingDocument class of the OpenXML SDK 2.0.
    Thursday, November 19, 2009 9:36 AM
  • Not quite sure about you request, if you just want to update content in the "/customXml/item1.xml" file, the following code should be ok.

      string sFileName = @"d:\ucm\test1.dotx";
                string sSourceXML = @"d:\ucm\test.xml";
                using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(sFileName, true))
                {
                    MainDocumentPart abc = wdDoc.MainDocumentPart;
                    CustomXmlPart cusPart= abc.CustomXmlParts.First();
                    cusPart.FeedData(new FileStream(sSourceXML, FileMode.Open, FileAccess.Read));
                   
                }

    Thursday, November 19, 2009 10:14 AM
  • All,

    Thanks a lot for your valuable inputs. But I am still no where.

    My requirement is to get a final word document from a template document which contains tags (custom xml). This template is created by inserting tags using a xsd file.
    This final word document should have the actual corresponding tag values from a xml file.
    Kindly refer to my very first post.
    And I want to use Open XML 2.0 for achieving this.
    Hope I am clear !

    Thanks in advance,
    Chandan 

    Friday, November 20, 2009 7:47 AM
  • Hi,

     

    Check this: http://www.devx.com/dotnet/Article/42221/1954

    Its exactly what you are looking for!

    MainDocumentPart mainPart = wordDoc.MainDocumentPart;
    mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);
    CustomXmlPart customXmlPart = mainPart.AddNewPart<CustomXmlPart>();
    StreamWriter ts = new StreamWriter(customXmlPart.GetStream());
    ts.Write(customXML);

    Wednesday, October 6, 2010 6:17 PM