Word OpenXML.在书签之间遍历OpenXmlElement [英] Word OpenXML . Traversing OpenXmlElements between bookmarks

查看:400
本文介绍了Word OpenXML.在书签之间遍历OpenXmlElement的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to traverse nodes between a bookmark start and a bookmark end tag. The problem appears to break down into a tree traversal but I am having trouble pinning down the correct algorithm. The bookmark start and end elements are non-composite nodes (no children) and may appear at an arbitrary depth in the tree. Bookmark start are also not guaranteed to be a at the same depth.

如果您为文档绘制树形结构,则需要检查开始和结束书签之间的所有节点.我认为遍历从节点x到节点y的不平衡树的算法会起作用.这听起来可行还是我错过了什么?

If you draw the tree structure for the document I would want to examine all nodes between the start and end bookmark. I think an algorithm to traverse an unbalanced tree starting at node x and ending at node y would work. Does this sounds feasible or am I missing something.

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

If this is feasible could you point me in the direction of a tree traversal that could accomplish returning the nodes?

推荐答案

这取决于您要执行的操作,但是,如果您主要对两个书签之间的文本感兴趣,那么这是XmlDocument/与LINQ to XML或Open XML SDK V2的强类型对象模型相比,XPath语义更易于使用. XPath的'following :: *'轴的语义是您想要的.下面的示例使用XmlDocument和XPath打印书签的开始和结束之间的节点名称.

This depends on what you want to do, however, if you are primarily interested in the text between two bookmarks, then this is one of those cases where XmlDocument / XPath semantics are easier to use than LINQ to XML or the strongly-typed object model of the Open XML SDK V2. The semantics of the 'following::*' axis of XPath is what you want. The following example uses XmlDocument and XPath to print the names of the nodes between the start and end of a bookmark.

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);
            }
        }
    }
}

这篇关于Word OpenXML.在书签之间遍历OpenXmlElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆