none
Issue parsing word document when inserting diagram into a rich text content control RRS feed

  • Question

  • Hi,

    I'm using OPCHelper in order to convert an open word document into a byte array(GetPackageStream slightly modified to accept a word document instead of Range). It works fine except when i insert a diagram into a rich text content control.

    If i invoke the method(which i've added down below) after adding the diagram i get the follwing exception: Invalid URI: The format of the URI could not be determined

    The reason for this exception is the fact that Target="NULL" in a Relationship which looks like this

    <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="NULL" TargetMode="External" xmlns="http://schemas.openxmlformats.org/package/2006/relationships" />

    The code/method that i use looks like this(i also added a comment in the code below to show exactly where the exception occurs):

            public static byte[] GetPackageStream(this Word.Document document)
            {
                XDocument doc = null;

                doc = XDocument.Parse(document.WordOpenXML);
               
                XNamespace pkg = "http://schemas.microsoft.com/office/2006/xmlPackage";
                XNamespace rel = "http://schemas.openxmlformats.org/package/2006/relationships";
                Package InmemoryPackage = null;
                byte[] output = null;

                using (MemoryStream memStream = new MemoryStream())
                {
                    using (InmemoryPackage = Package.Open(memStream, FileMode.Create))
                    {
                        // add all parts (but not relationships)
                        foreach (var xmlPart in doc.Root
                            .Elements()
                            .Where(p =>
                                (string)p.Attribute(pkg + "contentType") !=
                                "application/vnd.openxmlformats-package.relationships+xml"))
                        {
                            string name = (string)xmlPart.Attribute(pkg + "name");
                            string contentType = (string)xmlPart.Attribute(pkg + "contentType");
                            if (contentType.EndsWith("xml"))
                            {
                                Uri u = new Uri(name, UriKind.Relative);
                                PackagePart part = InmemoryPackage.CreatePart(u, contentType,
                                    CompressionOption.Normal);
                                using (Stream str = part.GetStream(FileMode.Create))
                                using (XmlWriter xmlWriter = XmlWriter.Create(str))
                                    xmlPart.Element(pkg + "xmlData")
                                        .Elements()
                                        .First()
                                        .WriteTo(xmlWriter);
                            }
                            else
                            {
                                Uri u = new Uri(name, UriKind.Relative);
                                PackagePart part = InmemoryPackage.CreatePart(u, contentType,
                                    CompressionOption.Normal);
                                using (Stream str = part.GetStream(FileMode.Create))
                                using (BinaryWriter binaryWriter = new BinaryWriter(str))
                                {
                                    string base64StringInChunks =
                                   (string)xmlPart.Element(pkg + "binaryData");
                                    char[] base64CharArray = base64StringInChunks
                                        .Where(c => c != '\r' && c != '\n').ToArray();
                                    byte[] byteArray =
                                        System.Convert.FromBase64CharArray(base64CharArray,
                                        0, base64CharArray.Length);
                                    binaryWriter.Write(byteArray);
                                }
                            }
                        }
                        foreach (var xmlPart in doc.Root.Elements())
                        {
                            string name = (string)xmlPart.Attribute(pkg + "name");
                            string contentType = (string)xmlPart.Attribute(pkg + "contentType");
                            if (contentType ==
                                "application/vnd.openxmlformats-package.relationships+xml")
                            {
                                // add the package level relationships
                                if (name == "/_rels/.rels")
                                {
                                    foreach (XElement xmlRel in
                                        xmlPart.Descendants(rel + "Relationship"))
                                    {
                                        string id = (string)xmlRel.Attribute("Id");
                                        string type = (string)xmlRel.Attribute("Type");
                                        string target = (string)xmlRel.Attribute("Target");
                                        string targetMode =
                                            (string)xmlRel.Attribute("TargetMode");
                                        if (targetMode == "External")
                                            InmemoryPackage.CreateRelationship(
                                                new Uri(target, UriKind.Absolute),
                                                TargetMode.External, type, id);
                                        else
                                            InmemoryPackage.CreateRelationship(
                                                new Uri(target, UriKind.Relative),
                                                TargetMode.Internal, type, id);
                                    }
                                }
                                else
                                // add part level relationships
                                {
                                    string directory = name.Substring(0, name.IndexOf("/_rels"));
                                    string relsFilename = name.Substring(name.LastIndexOf('/'));
                                    string filename =
                                        relsFilename.Substring(0, relsFilename.IndexOf(".rels"));
                                    PackagePart fromPart = InmemoryPackage.GetPart(
                                        new Uri(directory + filename, UriKind.Relative));
                                    foreach (XElement xmlRel in
                                        xmlPart.Descendants(rel + "Relationship"))
                                    {
                                        string id = (string)xmlRel.Attribute("Id");
                                        string type = (string)xmlRel.Attribute("Type");
                                        string target = (string)xmlRel.Attribute("Target");
                                        string targetMode =
                                            (string)xmlRel.Attribute("TargetMode");

    //PLEASE NOTE: The variable target contains "NULL" if adding diagram to rich text content control. The exception Invalid URI: The format of the URI could not be determined is thrown when creating a new Uri in the else-statement.

                                        if (targetMode == "External")
                                            fromPart.CreateRelationship(
                                                new Uri(target, UriKind.Absolute),
                                                TargetMode.External, type, id);
                                        else
                                            fromPart.CreateRelationship(
                                                new Uri(target, UriKind.Relative),
                                                TargetMode.Internal, type, id);
                                    }
                                }
                            }
                        }

                        InmemoryPackage.Flush();
                    }


                    // Modify the document to ensure it is correctly marked as a macro enabled Document
                    using (WordprocessingDocument wDocument = WordprocessingDocument.Open(memStream, true))
                    {
                        wDocument.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.MacroEnabledDocument);
                    }

                    memStream.Position = 0;
                    output = new byte[memStream.Length];
                    memStream.Read(output, 0, output.Length);
                }

                return output;
            }

    Any ideas anyone?

    Br,

    /Peter


    Peter


    Friday, February 27, 2015 2:41 PM

Answers

  • Hi Peter,

    According to the description, you are using OPCHelper converting the Word document into byte. As far as I know, the OPCHelper is a third-part class, I suggest contact the vendor to get more effective response.

    For this issue, did you want to retrieve byte data from the Office package? And based on my understanding, the office document support Open XML format is a zip. We can directly get the data from the zip package via GZipStream.

    Hope it is helpful, and if I misunderstood please feel free to correct me.

    Regards & Fei 


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, March 2, 2015 2:10 AM
    Moderator

All replies

  • Hi Peter,

    According to the description, you are using OPCHelper converting the Word document into byte. As far as I know, the OPCHelper is a third-part class, I suggest contact the vendor to get more effective response.

    For this issue, did you want to retrieve byte data from the Office package? And based on my understanding, the office document support Open XML format is a zip. We can directly get the data from the zip package via GZipStream.

    Hope it is helpful, and if I misunderstood please feel free to correct me.

    Regards & Fei 


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, March 2, 2015 2:10 AM
    Moderator
  • Hi,

    Thanks for your reply.

    I guess it's a third party library but i downloaded it from office dev center

    https://code.msdn.microsoft.com/office/Improve-Automation-415bff13#content

    Anyway, the document that i'm trying to convert is my currently open document and from what i can see using GZipStream i must save the document temporarily to disc in order to get a stream and then use GZipStream. I was hoping not to use extra overhead that comes with first saving the document to the disc.

    Br,


    Peter

    Monday, March 2, 2015 12:40 PM