C# 使用INCLUDETEXT字段访问包含的文档中的CustomXMLPart

C# 使用INCLUDETEXT字段访问包含的文档中的CustomXMLPart,c#,vsto,ms-office,openxml,openxml-sdk,C#,Vsto,Ms Office,Openxml,Openxml Sdk,我有一个docx Word文档,其中包含绑定到CustomXMLPart中数据的内容控件 然后使用INCLUDETEXT将此文档(或其中的书签)包含在另一个Word文档中 当第一个文档包含在第二个文档中时,是否有任何方法可以从原始文档中获取CustomXMLPart(我已经在Word中运行了一个VSTO Word加载项来查看文档) 我要做的是将它与第二个文档中已经存在的CustomXMLParts合并,以便内容控件仍然绑定到XMLPart中的数据 或者,有没有其他方法不使用INCLUDETEXT

我有一个docx Word文档,其中包含绑定到CustomXMLPart中数据的内容控件

然后使用INCLUDETEXT将此文档(或其中的书签)包含在另一个Word文档中

当第一个文档包含在第二个文档中时,是否有任何方法可以从原始文档中获取CustomXMLPart(我已经在Word中运行了一个VSTO Word加载项来查看文档)

我要做的是将它与第二个文档中已经存在的CustomXMLParts合并,以便内容控件仍然绑定到XMLPart中的数据


或者,有没有其他方法不使用INCLUDETEXT字段来实现这一点?

我认为使用VSTO和INCLUDETEXT字段可能无法实现这一点,并研究了使用AltChunk作为替代方法

在打开该文件之前,我已经在使用OpenXMLSDK2对该文件进行一些处理,以便能够完成将文档合并到一起所需的额外工作

尽管使用altChunk方法会将整个第二个文档嵌入第一个文档中,包括它自己的CustomXmlParts,但是当打开文档并且第二个文档与第一个文档合并时,CustomXmlParts会被Word丢弃

我最终得到了类似于下面的代码。它用altChunk数据替换定义的内容控件,并将特定的CustomXmlParts合并在一起

    private static void CreateAltChunksInWordDocument(WordprocessingDocument doc, string externalDocumentPath)
    {
        foreach (var control in doc.ContentControls().ToList()) //Have to do .ToList() on this as when we update the Doc in the loop it stops enumerating otherwise
        {
            SdtProperties props = control.Elements<SdtProperties>().FirstOrDefault();
            if (props == null)
                continue;

            SdtAlias alias = props.Elements<SdtAlias>().FirstOrDefault();
            if (alias == null || !alias.Val.HasValue || alias.Val.Value != "External Template")
                continue;

            using (WordprocessingDocument externaldoc = WordprocessingDocument.Open(externalDocumentPath, false))
            {
                //Replace the Content Control with an AltChunk section, and stream in the external file
                string altChunkId = "AltChunkId" + Guid.NewGuid().ToString().Replace("{", "").Replace("}", "").Replace("-", "");

                AlternativeFormatImportPart chunk = doc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
                chunk.FeedData(File.OpenRead(externalDocumentPath));

                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;

                OpenXmlElement parent = control.Parent;
                parent.InsertAfter(altChunk, control);
                control.Remove();

                XDocument xDocMain;
                CustomXmlPart partMain = MyCommon.GetMyXmlPart(doc.MainDocumentPart, out xDocMain);

                XDocument xDocExternal;
                CustomXmlPart partExternal = MyCommon.GetMyXmlPart(externaldoc.MainDocumentPart, out xDocExternal);

                if (xDocMain != null && partMain != null && xDocExternal != null && partExternal != null)
                {
                    MyCommon.MergeXmlPartFields(xDocMain, xDocExternal);

                    //Save the updated part
                    using (Stream outputStream = partMain.GetStream())
                    {
                        using (StreamWriter ts = new StreamWriter(outputStream))
                        {
                            ts.Write(xDocMain.ToString());
                        }
                    }
                }
            }
        }
    }
私有静态void CreateAltChunksInWordDocument(WordprocessingDocument文档,字符串externalDocumentPath)
{
foreach(doc.ContentControls().ToList()中的var-control)//必须对其执行.ToList(),因为当我们更新循环中的文档时,它会停止枚举,否则
{
SdtProperties props=control.Elements().FirstOrDefault();
if(props==null)
继续;
SdtAlias alias=props.Elements().FirstOrDefault();
if(alias==null | | |!alias.Val.HasValue | | alias.Val.Value!=“外部模板”)
继续;
使用(wordprocessingdocumentexternaldoc=WordprocessingDocument.Open(externalDocumentPath,false))
{
//将内容控件替换为AltChunk节,并在外部文件中进行流处理
字符串altChunkId=“altChunkId”+Guid.NewGuid().ToString().Replace(“{”,“”)。Replace(“}”,“”)。Replace(“-”,“”);
AlternativeFormatImportPart chunk=doc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML,altChunkId);
FeedData(File.OpenRead(externalDocumentPath));
AltChunk AltChunk=新的AltChunk();
altChunk.Id=altChunkId;
OpenXmlElement parent=control.parent;
parent.InsertAfter(altChunk,控件);
控件。移除();
xdocumentxdocmain;
CustomXmlPart partMain=MyCommon.GetMyXmlPart(doc.MainDocumentPart,out-xDocMain);
XDocument XDocternal;
CustomXmlPart parternal=MyCommon.GetMyXmlPart(externaldoc.MainDocumentPart,out-xDocExternal);
if(xDocMain!=null&&partMain!=null&&xDocExternal!=null&&partExternal!=null)
{
MyCommon.MergeXmlPartFields(xDocMain、xDocExternal);
//保存更新的零件
使用(Stream outputStream=partMain.GetStream())
{
使用(StreamWriter ts=新StreamWriter(outputStream))
{
ts.Write(xDocMain.ToString());
}
}
}
}
}
}

我认为使用VSTO和IncludeText字段可能无法做到这一点,并研究了使用AltChunk作为替代方法

在打开该文件之前,我已经在使用OpenXMLSDK2对该文件进行一些处理,以便能够完成将文档合并到一起所需的额外工作

尽管使用altChunk方法会将整个第二个文档嵌入第一个文档中,包括它自己的CustomXmlParts,但是当打开文档并且第二个文档与第一个文档合并时,CustomXmlParts会被Word丢弃

我最终得到了类似于下面的代码。它用altChunk数据替换定义的内容控件,并将特定的CustomXmlParts合并在一起

    private static void CreateAltChunksInWordDocument(WordprocessingDocument doc, string externalDocumentPath)
    {
        foreach (var control in doc.ContentControls().ToList()) //Have to do .ToList() on this as when we update the Doc in the loop it stops enumerating otherwise
        {
            SdtProperties props = control.Elements<SdtProperties>().FirstOrDefault();
            if (props == null)
                continue;

            SdtAlias alias = props.Elements<SdtAlias>().FirstOrDefault();
            if (alias == null || !alias.Val.HasValue || alias.Val.Value != "External Template")
                continue;

            using (WordprocessingDocument externaldoc = WordprocessingDocument.Open(externalDocumentPath, false))
            {
                //Replace the Content Control with an AltChunk section, and stream in the external file
                string altChunkId = "AltChunkId" + Guid.NewGuid().ToString().Replace("{", "").Replace("}", "").Replace("-", "");

                AlternativeFormatImportPart chunk = doc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
                chunk.FeedData(File.OpenRead(externalDocumentPath));

                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;

                OpenXmlElement parent = control.Parent;
                parent.InsertAfter(altChunk, control);
                control.Remove();

                XDocument xDocMain;
                CustomXmlPart partMain = MyCommon.GetMyXmlPart(doc.MainDocumentPart, out xDocMain);

                XDocument xDocExternal;
                CustomXmlPart partExternal = MyCommon.GetMyXmlPart(externaldoc.MainDocumentPart, out xDocExternal);

                if (xDocMain != null && partMain != null && xDocExternal != null && partExternal != null)
                {
                    MyCommon.MergeXmlPartFields(xDocMain, xDocExternal);

                    //Save the updated part
                    using (Stream outputStream = partMain.GetStream())
                    {
                        using (StreamWriter ts = new StreamWriter(outputStream))
                        {
                            ts.Write(xDocMain.ToString());
                        }
                    }
                }
            }
        }
    }
私有静态void CreateAltChunksInWordDocument(WordprocessingDocument文档,字符串externalDocumentPath)
{
foreach(doc.ContentControls().ToList()中的var-control)//必须对其执行.ToList(),因为当我们更新循环中的文档时,它会停止枚举,否则
{
SdtProperties props=control.Elements().FirstOrDefault();
if(props==null)
继续;
SdtAlias alias=props.Elements().FirstOrDefault();
if(alias==null | | |!alias.Val.HasValue | | alias.Val.Value!=“外部模板”)
继续;
使用(wordprocessingdocumentexternaldoc=WordprocessingDocument.Open(externalDocumentPath,false))
{
//将内容控件替换为AltChunk节,并在外部文件中进行流处理
字符串altChunkId=“altChunkId”+Guid.NewGuid().ToString().Replace(“{”,“”)。Replace(“}”,“”)。Replace(“-”,“”);
AlternativeFormatImportPart chunk=doc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML,altChunkId);
FeedData(File.OpenRead(externalDocumentPath));
AltChunk AltChunk=新的AltChunk();
altChunk.Id=altChunkId;
OpenXmlElement parent=control.parent;
parent.InsertAfter(altChunk,控件);
控件。移除();
xdocumentxdocmain;
CustomXmlPart partMain=MyCom