【问题标题】:Word OpenXML . Traversing OpenXmlElements between bookmarks字 OpenXML 。在书签之间遍历 OpenXmlElements
【发布时间】:2009-11-11 22:52:27
【问题描述】:

我需要遍历书签开始和书签结束标记之间的节点。该问题似乎分解为树遍历,但我无法确定正确的算法。书签开始和结束元素是非复合节点(没有子节点),可能出现在树中的任意深度。书签开始也不能保证在同一深度。

如果您为文档绘制树形结构,我想检查开始和结束书签之间的所有节点。我认为一种算法可以遍历从节点 x 开始并在节点 y 结束的不平衡树。这听起来可行还是我错过了什么。

如果这是可行的,您能否指出可以完成返回节点的树遍历的方向?

【问题讨论】:

    标签: c# openxml openxml-sdk


    【解决方案1】:

    这取决于您想要做什么,但是,如果您主要对两个书签之间的文本感兴趣,那么这是 XmlDocument / XPath 语义比 LINQ to XML 或强- Open XML SDK V2 的类型化对象模型。 XPath 的“following::*”轴的语义就是您想要的。以下示例使用 XmlDocument 和 XPath 打印书签开始和结束之间的节点名称。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    
    class Program
    {
        public static XmlDocument GetXmlDocument(OpenXmlPart part)
        {
            XmlDocument xmlDoc = new XmlDocument();
            using (Stream partStream = part.GetStream())
            using (XmlReader partXmlReader = XmlReader.Create(partStream))
                xmlDoc.Load(partXmlReader);
            return xmlDoc;
        }
    
        static void Main(string[] args)
        {
            using (WordprocessingDocument doc =
                WordprocessingDocument.Open("Test.docx", false))
            {
                XmlDocument xmlDoc = GetXmlDocument(doc.MainDocumentPart);
                string wordNamespace =
                    "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
                XmlNamespaceManager nsmgr =
                    new XmlNamespaceManager(xmlDoc.NameTable);
                nsmgr.AddNamespace("w", wordNamespace);
                XmlElement bookmarkStart = (XmlElement)xmlDoc.SelectSingleNode("descendant::w:bookmarkStart[@w:id='0']", nsmgr);
                XmlNodeList nodesFollowing = bookmarkStart.SelectNodes("following::*", nsmgr);
                var nodesBetween = nodesFollowing
                    .Cast<XmlNode>()
                    .TakeWhile(n =>
                        {
                            if (n.Name != "w:bookmarkEnd")
                                return true;
                            if (n.Attributes.Cast<XmlAttribute>().Any(a => a.Name == "w:id" && a.Value == "0"))
                                return false;
                            return true;
                        });
                foreach (XmlElement item in nodesBetween)
                {
                    Console.WriteLine(item.Name);
                    if (item.Name == "w:bookmarkStart" || item.Name == "w:bookmarkEnd")
                        foreach (XmlAttribute att in item.Attributes)
                            Console.WriteLine("{0}:{1}", att.Name, att.Value);
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我整理了一个算法,可以轻松检索书签的文本。

      How to Retrieve the Text of a Bookmark from an OpenXML WordprocessingML Document

      我还编写了代码来替换书签的文本:

      Replacing Text of a Bookmark in an OpenXML WordprocessingML Document

      -埃里克

      【讨论】:

      • 我认为这些链接已经失效。
      • 他们死了。 SQL Server 错误。这就是为什么好的答案不仅仅是链接。
      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2018-08-01
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多