5

ブックマークの開始タグとブックマークの終了タグの間でノードをトラバースする必要があります。問題はツリー トラバーサルに分解されるように見えますが、正しいアルゴリズムを特定するのに苦労しています。ブックマークの開始要素と終了要素は非複合ノード (子なし) であり、ツリー内の任意の深さに表示される場合があります。ブックマークの開始も同じ深さであるとは限りません。

ドキュメントのツリー構造を描画する場合、開始ブックマークと終了ブックマークの間のすべてのノードを調べたいと思います。ノード x から始まり、ノード y で終わる不均衡なツリーをたどるアルゴリズムが機能すると思います。これは実行可能に聞こえますか、それとも何か不足していますか。

これが実現可能である場合、ノードを返すことができるツリー トラバーサルの方向を教えていただけますか?

4

2 に答える 2

3

これは何をしたいかによって異なりますが、主に 2 つのブックマークの間のテキストに関心がある場合は、LINQ to XML や厳密に型指定されたオブジェクト モデルよりも XmlDocument / XPath セマンティクスの方が使いやすいケースの 1 つです。 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);
            }
        }
    }
}
于 2011-05-15T11:54:29.800 に答える
1

ブックマークのテキストを簡単に取得できるアルゴリズムをまとめました。

OpenXML WordprocessingML ドキュメントからブックマークのテキストを取得する方法

ブックマークのテキストを置き換えるコードも作成しました。

OpenXML WordprocessingML ドキュメントのブックマークのテキストを置き換える

-エリック

于 2011-09-09T14:23:42.070 に答える