public static XDocument GetXDocument(this OpenXmlPart part, out XmlNamespaceManager namespaceManager)
        {
            if (part == null)
            {
                throw new ArgumentNullException(nameof(part));
            }

            namespaceManager = part.Annotation <XmlNamespaceManager>();
            var partXDocument = part.Annotation <XDocument>();

            if (partXDocument != null)
            {
                if (namespaceManager != null)
                {
                    return(partXDocument);
                }

                namespaceManager = GetManagerFromXDocument(partXDocument);
                part.AddAnnotation(namespaceManager);

                return(partXDocument);
            }

            using (Stream partStream = part.GetStream())
            {
                if (partStream.Length == 0)
                {
                    partXDocument = new XDocument {
                        Declaration = new XDeclaration("1.0", "UTF-8", "yes")
                    };
                    part.AddAnnotation(partXDocument);

                    return(partXDocument);
                }

                using (XmlReader partXmlReader = XmlReader.Create(partStream))
                {
                    partXDocument = XDocument.Load(partXmlReader);
                    XmlNameTable nameTable = partXmlReader.NameTable ?? throw new Exception("NameTable is null.");
                    namespaceManager = new XmlNamespaceManager(nameTable);

                    part.AddAnnotation(partXDocument);
                    part.AddAnnotation(namespaceManager);

                    return(partXDocument);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Gets the XDocument for a part
        /// </summary>
        public static XDocument GetXDocument(this OpenXmlPart part)
        {
            XDocument xdoc = part.Annotation <XDocument>();

            if (xdoc != null)
            {
                return(xdoc);
            }
            try
            {
                using (StreamReader sr = new StreamReader(part.GetStream()))
                    using (XmlReader xr = XmlReader.Create(sr))
                    {
                        xdoc           = XDocument.Load(xr);
                        xdoc.Changed  += ElementChanged;
                        xdoc.Changing += ElementChanged;
                    }
            }
            catch (XmlException)
            {
                xdoc = new XDocument();
                xdoc.AddAnnotation(new ChangedSemaphore());
            }
            part.AddAnnotation(xdoc);
            return(xdoc);
        }
예제 #3
0
 public static XDocument GetXDocument(this OpenXmlPart part)
 {
     try
     {
         XDocument partXDocument = part.Annotation <XDocument>();
         if (partXDocument != null)
         {
             return(partXDocument);
         }
         using (Stream partStream = part.GetStream())
         {
             if (partStream.Length == 0)
             {
                 partXDocument             = new XDocument();
                 partXDocument.Declaration = new XDeclaration("1.0", "UTF-8", "yes");
             }
             else
             {
                 using (XmlReader partXmlReader = XmlReader.Create(partStream))
                     partXDocument = XDocument.Load(partXmlReader);
             }
         }
         part.AddAnnotation(partXDocument);
         return(partXDocument);
     }
     catch (Exception e)
     {
         throw e;
     }
 }
        public static XDocument GetXDocument(this OpenXmlPart part)
        {
            if (part == null)
            {
                throw new ArgumentNullException(nameof(part));
            }

            var partXDocument = part.Annotation <XDocument>();

            if (partXDocument != null)
            {
                return(partXDocument);
            }

            using (Stream partStream = part.GetStream())
            {
                if (partStream.Length == 0)
                {
                    partXDocument = new XDocument {
                        Declaration = new XDeclaration("1.0", "UTF-8", "yes")
                    };
                }
                else
                {
                    using (XmlReader partXmlReader = XmlReader.Create(partStream))
                    {
                        partXDocument = XDocument.Load(partXmlReader);
                    }
                }
            }

            part.AddAnnotation(partXDocument);
            return(partXDocument);
        }
        private XDocument LoadPart(OpenXmlPart source)
	    {
		    if (source == null) return null;

			var part = source.Annotation<XDocument>();
		    if (part != null) return part;

		    using (var str = source.GetStream())
		    using (var streamReader = new StreamReader(str))
		    using (var xr = XmlReader.Create(streamReader))
			    part = XDocument.Load(xr);
		    return part;
	    }
예제 #6
0
        public static XDocument GetXDocument(this OpenXmlPart part)
        {
            XDocument partXDocument = part.Annotation <XDocument>();

            if (partXDocument != null)
            {
                return(partXDocument);
            }
            using (Stream partStream = part.GetStream())
                using (XmlReader partXmlReader = XmlReader.Create(partStream))
                    partXDocument = XDocument.Load(partXmlReader);
            part.AddAnnotation(partXDocument);
            return(partXDocument);
        }
        public static XDocument GetXDocument(this OpenXmlPart part)
        {
            XDocument xdoc = part.Annotation <XDocument>();

            if (xdoc != null)
            {
                return(xdoc);
            }
            using (StreamReader sr = new StreamReader(part.GetStream()))
                using (XmlReader xr = XmlReader.Create(sr))
                    xdoc = XDocument.Load(xr);
            part.AddAnnotation(xdoc);
            return(xdoc);
        }
예제 #8
0
        /// <summary>
        /// Get the xml document for the open xml part.
        /// </summary>
        /// <param name="part">The openxml part to get.</param>
        /// <returns>The xml document</returns>
        protected XDocument GetXDocument(OpenXmlPart part)
        {
            XDocument xdoc = part.Annotation <XDocument>();

            if (xdoc != null)
            {
                return(xdoc);
            }

            using (StreamReader streamReader = new StreamReader(part.GetStream()))
                using (XmlReader xmlReader = XmlReader.Create(streamReader))
                    xdoc = XDocument.Load(xmlReader);

            part.AddAnnotation(xdoc);
            return(xdoc);
        }
예제 #9
0
 private static void FlushPart(OpenXmlPart part, HashSet<OpenXmlPart> visited)
 {
     visited.Add(part);
     XDocument xdoc = part.Annotation<XDocument>();
     if (xdoc != null && xdoc.Annotation<ChangedSemaphore>() != null)
     {
         using (XmlWriter xw = XmlWriter.Create(part.GetStream(FileMode.Create, FileAccess.Write)))
         {
             xdoc.Save(xw);
         }
         xdoc.RemoveAnnotations<ChangedSemaphore>();
         xdoc.Changing += ElementChanged;
         xdoc.Changed += ElementChanged;
     }
     foreach (IdPartPair item in part.Parts)
         if (!visited.Contains(item.OpenXmlPart))
             FlushPart(item.OpenXmlPart, visited);
 }
        private XDocument LoadPart(OpenXmlPart source)
        {
            if (source == null)
            {
                return(null);
            }

            var part = source.Annotation <XDocument>();

            if (part != null)
            {
                return(part);
            }

            using (var str = source.GetStream())
                using (var streamReader = new StreamReader(str))
                    using (var xr = XmlReader.Create(streamReader))
                        part = XDocument.Load(xr);

            return(part);
        }
예제 #11
0
        private static void FlushPart(OpenXmlPart part, HashSet <OpenXmlPart> visited)
        {
            visited.Add(part);
            XDocument xdoc = part.Annotation <XDocument>();

            if (xdoc != null && xdoc.Annotation <ChangedSemaphore>() != null)
            {
                using (XmlWriter xw = XmlWriter.Create(part.GetStream(FileMode.Create, FileAccess.Write)))
                {
                    xdoc.Save(xw);
                }
                xdoc.RemoveAnnotations <ChangedSemaphore>();
                xdoc.Changing += ElementChanged;
                xdoc.Changed  += ElementChanged;
            }
            foreach (IdPartPair item in part.Parts)
            {
                if (!visited.Contains(item.OpenXmlPart))
                {
                    FlushPart(item.OpenXmlPart, visited);
                }
            }
        }
        // prohibit
        // - altChunk
        // - subDoc
        // - contentPart

        // This strips all text nodes from the XML tree, thereby leaving only the structure.

        private static object CloneBlockLevelContentForHashing(
            OpenXmlPart mainDocumentPart,
            XNode node,
            bool includeRelatedParts,
            WmlComparerSettings settings)
        {
            if (node is XElement element)
            {
                if (element.Name == W.bookmarkStart ||
                    element.Name == W.bookmarkEnd ||
                    element.Name == W.pPr ||
                    element.Name == W.rPr)
                {
                    return(null);
                }

                if (element.Name == W.p)
                {
                    var clonedPara = new XElement(element.Name,
                                                  element.Attributes().Where(a => a.Name != W.rsid &&
                                                                             a.Name != W.rsidDel &&
                                                                             a.Name != W.rsidP &&
                                                                             a.Name != W.rsidR &&
                                                                             a.Name != W.rsidRDefault &&
                                                                             a.Name != W.rsidRPr &&
                                                                             a.Name != W.rsidSect &&
                                                                             a.Name != W.rsidTr &&
                                                                             a.Name.Namespace != PtOpenXml.pt),
                                                  element.Nodes().Select(n =>
                                                                         CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));

                    IEnumerable <IGrouping <bool, XElement> > groupedRuns = clonedPara
                                                                            .Elements()
                                                                            .GroupAdjacent(e => e.Name == W.r &&
                                                                                           e.Elements().Count() == 1 &&
                                                                                           e.Element(W.t) != null);

                    var clonedParaWithGroupedRuns = new XElement(element.Name,
                                                                 groupedRuns.Select(g =>
                    {
                        if (g.Key)
                        {
                            string text = g.Select(t => t.Value).StringConcatenate();
                            if (settings.CaseInsensitive)
                            {
                                text = text.ToUpper(settings.CultureInfo);
                            }
                            var newRun = (object)new XElement(W.r,
                                                              new XElement(W.t,
                                                                           text));
                            return(newRun);
                        }

                        return(g);
                    }));

                    return(clonedParaWithGroupedRuns);
                }

                if (element.Name == W.r)
                {
                    IEnumerable <XElement> clonedRuns = element
                                                        .Elements()
                                                        .Where(e => e.Name != W.rPr)
                                                        .Select(rc => new XElement(W.r,
                                                                                   CloneBlockLevelContentForHashing(mainDocumentPart, rc, includeRelatedParts, settings)));
                    return(clonedRuns);
                }

                if (element.Name == W.tbl)
                {
                    var clonedTable = new XElement(W.tbl,
                                                   element.Elements(W.tr).Select(n =>
                                                                                 CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(clonedTable);
                }

                if (element.Name == W.tr)
                {
                    var clonedRow = new XElement(W.tr,
                                                 element.Elements(W.tc).Select(n =>
                                                                               CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(clonedRow);
                }

                if (element.Name == W.tc)
                {
                    var clonedCell = new XElement(W.tc,
                                                  element.Elements().Select(n =>
                                                                            CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(clonedCell);
                }

                if (element.Name == W.tcPr)
                {
                    var clonedCellProps = new XElement(W.tcPr,
                                                       element.Elements(W.gridSpan).Select(n =>
                                                                                           CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(clonedCellProps);
                }

                if (element.Name == W.gridSpan)
                {
                    var clonedGridSpan = new XElement(W.gridSpan,
                                                      new XAttribute("val", (string)element.Attribute(W.val)));
                    return(clonedGridSpan);
                }

                if (element.Name == W.txbxContent)
                {
                    var clonedTextbox = new XElement(W.txbxContent,
                                                     element.Elements().Select(n =>
                                                                               CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(clonedTextbox);
                }

                if (includeRelatedParts)
                {
                    if (ComparisonUnitWord.ElementsWithRelationshipIds.Contains(element.Name))
                    {
                        var newElement = new XElement(element.Name,
                                                      element.Attributes()
                                                      .Where(a => a.Name.Namespace != PtOpenXml.pt)
                                                      .Where(a => !AttributesToTrimWhenCloning.Contains(a.Name))
                                                      .Select(a =>
                        {
                            if (!ComparisonUnitWord.RelationshipAttributeNames.Contains(a.Name))
                            {
                                return(a);
                            }

                            var rId = (string)a;

                            // could be an hyperlink relationship
                            try
                            {
                                OpenXmlPart oxp = mainDocumentPart.GetPartById(rId);
                                if (oxp == null)
                                {
                                    throw new FileFormatException("Invalid WordprocessingML Document");
                                }

                                var anno = oxp.Annotation <PartSHA1HashAnnotation>();
                                if (anno != null)
                                {
                                    return(new XAttribute(a.Name, anno.Hash));
                                }

                                if (!oxp.ContentType.EndsWith("xml"))
                                {
                                    using (Stream str = oxp.GetStream())
                                    {
                                        byte[] ba;
                                        using (var br = new BinaryReader(str))
                                        {
                                            ba = br.ReadBytes((int)str.Length);
                                        }

                                        string sha1 = WmlComparerUtil.SHA1HashStringForByteArray(ba);
                                        oxp.AddAnnotation(new PartSHA1HashAnnotation(sha1));
                                        return(new XAttribute(a.Name, sha1));
                                    }
                                }
                            }
                            catch (ArgumentOutOfRangeException)
                            {
                                HyperlinkRelationship hr =
                                    mainDocumentPart.HyperlinkRelationships.FirstOrDefault(z => z.Id == rId);
                                if (hr != null)
                                {
                                    string str = hr.Uri.ToString();
                                    return(new XAttribute(a.Name, str));
                                }

                                // could be an external relationship
                                ExternalRelationship er =
                                    mainDocumentPart.ExternalRelationships.FirstOrDefault(z => z.Id == rId);
                                if (er != null)
                                {
                                    string str = er.Uri.ToString();
                                    return(new XAttribute(a.Name, str));
                                }

                                return(new XAttribute(a.Name, "NULL Relationship"));
                            }

                            return(null);
                        }),
                                                      element.Nodes().Select(n =>
                                                                             CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                        return(newElement);
                    }
                }

                if (element.Name == VML.shape)
                {
                    return(new XElement(element.Name,
                                        element.Attributes()
                                        .Where(a => a.Name.Namespace != PtOpenXml.pt)
                                        .Where(a => a.Name != "style" && a.Name != "id" && a.Name != "type"),
                                        element.Nodes().Select(n =>
                                                               CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings))));
                }

                if (element.Name == O.OLEObject)
                {
                    var o = new XElement(element.Name,
                                         element.Attributes()
                                         .Where(a => a.Name.Namespace != PtOpenXml.pt)
                                         .Where(a => a.Name != "ObjectID" && a.Name != R.id),
                                         element.Nodes().Select(n =>
                                                                CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(o);
                }

                if (element.Name == W._object)
                {
                    var o = new XElement(element.Name,
                                         element.Attributes()
                                         .Where(a => a.Name.Namespace != PtOpenXml.pt),
                                         element.Nodes().Select(n =>
                                                                CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings)));
                    return(o);
                }

                if (element.Name == WP.docPr)
                {
                    return(new XElement(element.Name,
                                        element.Attributes()
                                        .Where(a => a.Name.Namespace != PtOpenXml.pt && a.Name != "id"),
                                        element.Nodes().Select(n =>
                                                               CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings))));
                }

                return(new XElement(element.Name,
                                    element.Attributes()
                                    .Where(a => a.Name.Namespace != PtOpenXml.pt)
                                    .Where(a => !AttributesToTrimWhenCloning.Contains(a.Name)),
                                    element.Nodes().Select(n =>
                                                           CloneBlockLevelContentForHashing(mainDocumentPart, n, includeRelatedParts, settings))));
            }

            if (settings.CaseInsensitive)
            {
                if (node is XText xt)
                {
                    string newText = xt.Value.ToUpper(settings.CultureInfo);
                    return(new XText(newText));
                }
            }

            return(node);
        }