Node

Node class

Word 文档所有节点的基类。

public abstract class Node

特性

姓名 描述
CustomNodeId { get; set; } 指定自定义节点标识符。
virtual Document { get; } 获取该节点所属的文档。
virtual IsComposite { get; } 如果此节点可以包含其他节点,则返回 true。
NextSibling { get; } 获取紧跟此节点的节点。
abstract NodeType { get; } 获取此节点的类型。
ParentNode { get; } 获取此节点的直接父节点。
PreviousSibling { get; } 获取紧接在此节点之前的节点。
Range { get; } 返回一个 范围表示此节点中包含的文档部分的对象。

方法

姓名 描述
abstract Accept(DocumentVisitor) 接受访客。
Clone(bool) 创建节点的副本。
GetAncestor(NodeType) 获取指定的第一个祖先NodeType.
GetAncestor(Type) 获取指定对象类型的第一个祖先。
virtual GetText() 获取该节点及其所有子节点的文本。
NextPreOrder(Node) 根据前序树遍历算法获取下一个节点。
PreviousPreOrder(Node) 根据前序树遍历算法获取上一个节点。
Remove() 从父级中移除自身。
ToString(SaveFormat) 将节点的内容导出为指定格式的字符串。
ToString(SaveOptions) 使用指定的保存选项将节点的内容导出为字符串。
static NodeTypeToString(NodeType) 一种将节点类型枚举值转换为用户友好字符串的实用方法。

评论

文档表示为节点树,类似于 DOM 或 XmlDocument。

有关详细信息,请参阅复合设计模式。

Node班级:

  • 定义子节点接口。
  • 定义访问节点的接口。
  • 提供默认克隆功能。
  • 实现父节点和所有者文档机制。
  • 实现对兄弟节点的访问。

例子

显示如何从复合节点中删除特定类型的所有子节点。

Document doc = new Document(MyDir + "Tables.docx");

Assert.AreEqual(2, doc.GetChildNodes(NodeType.Table, true).Count);

Node curNode = doc.FirstSection.Body.FirstChild;

while (curNode != null)
{
    // 将下一个兄弟节点保存为变量,以防我们在删除该节点后想要移动到它。
    Node nextNode = curNode.NextSibling;

    // 一个section body可以包含Paragraph和Table节点。
    // 如果节点是表,则将其从父节点中移除。
    if (curNode.NodeType == NodeType.Table)
        curNode.Remove();

    curNode = nextNode;
}

Assert.AreEqual(0, doc.GetChildNodes(NodeType.Table, true).Count);

显示如何克隆复合节点。

Document doc = new Document();
Paragraph para = doc.FirstSection.Body.FirstParagraph;
para.AppendChild(new Run(doc, "Hello world!"));

// 下面是克隆复合节点的两种方法。
// 1 - 创建一个节点的克隆,并创建其每个子节点的克隆。
Node cloneWithChildren = para.Clone(true);

Assert.IsTrue(((CompositeNode)cloneWithChildren).HasChildNodes);
Assert.AreEqual("Hello world!", cloneWithChildren.GetText().Trim());

// 2 - 单独创建一个节点的克隆,没有任何子节点。
Node cloneWithoutChildren = para.Clone(false);

Assert.IsFalse(((CompositeNode)cloneWithoutChildren).HasChildNodes);
Assert.AreEqual(string.Empty, cloneWithoutChildren.GetText().Trim());

显示如何遍历复合节点的子节点集合。

Document doc = new Document();

// 将两个运行和一个形状作为子节点添加到该文档的第一段。
Paragraph paragraph = (Paragraph)doc.GetChild(NodeType.Paragraph, 0, true);
paragraph.AppendChild(new Run(doc, "Hello world! "));

Shape shape = new Shape(doc, ShapeType.Rectangle);
shape.Width = 200;
shape.Height = 200;
// 请注意,'CustomNodeId' 不会保存到输出文件中,并且仅在节点生命周期内存在。
shape.CustomNodeId = 100;
shape.WrapType = WrapType.Inline;
paragraph.AppendChild(shape);

paragraph.AppendChild(new Run(doc, "Hello again!"));

// 遍历段落的直接子元素集合,
// 并打印我们在其中找到的任何运行或形状。
NodeCollection children = paragraph.ChildNodes;

Assert.AreEqual(3, paragraph.ChildNodes.Count);

foreach (Node child in children)
    switch (child.NodeType)
    {
        case NodeType.Run:
            Console.WriteLine("Run contents:");
            Console.WriteLine($"\t\"{child.GetText().Trim()}\"");
            break;
        case NodeType.Shape:
            Shape childShape = (Shape)child;
            Console.WriteLine("Shape:");
            Console.WriteLine($"\t{childShape.ShapeType}, {childShape.Width}x{childShape.Height}");
    }

也可以看看