Đây là "Halloween vấn đề", gọi như vậy vì nó được chú ý bởi một số nhà phát triển trên Halloween, và nó trông ghê rợn đối với họ. Đó là vấn đề của việc sử dụng mã khai báo (truy vấn) với mã bắt buộc (xóa các nút) cùng một lúc. Nếu bạn suy nghĩ về nó, bạn đang lặp đi lặp lại mặc dù một danh sách liên kết, và nếu bạn bắt đầu xóa các nút trong danh sách liên kết, bạn hoàn toàn mess up the iterator. Cách đơn giản hơn để tránh vấn đề này là "hiện thực hóa" kết quả của truy vấn trong Danh sách, và sau đó bạn có thể lặp qua danh sách và xóa các nút theo ý muốn. Sự khác biệt duy nhất trong đoạn mã sau là nó gọi ToList sau khi gọi trục Descendants.
MainDocumentPart mainpart = doc.MainDocumentPart;
IEnumerable<OpenXmlElement> elems = mainPart.Document.Body.Descendants().ToList();
foreach(OpenXmlElement elem in elems){
if(elem is Text && elem.InnerText == "##MY_PLACE_HOLDER##")
{
Run run = (Run)elem.Parent;
Paragraph p = (Paragraph)run.Parent;
p.RemoveAllChildren();
p.Remove();
}
}
Tuy nhiên, tôi phải lưu ý rằng tôi thấy một lỗi khác trong mã của bạn. Không có gì để ngăn chặn Word tách nút văn bản đó thành nhiều phần tử văn bản từ nhiều lần chạy. Mặc dù trong hầu hết các trường hợp, mã của bạn sẽ hoạt động tốt, sớm hay muộn, bạn hoặc người dùng sẽ thực hiện một số hành động (như chọn ký tự và vô tình nhấn nút in đậm trên ruy-băng) và sau đó mã của bạn sẽ không hoạt động nữa.
Nếu bạn thực sự muốn làm việc ở cấp văn bản, thì bạn cần phải sử dụng mã như những gì tôi giới thiệu trong này màn hình-cast: http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2011/08/04/introducing-textreplacer-a-new-class-for-powertools-for-open-xml.aspx
Trong thực tế, bạn có thể có thể sử dụng mã đúng nguyên văn để xử lý của bạn trường hợp sử dụng, tôi tin.
cách tiếp cận khác, linh hoạt hơn và mạnh mẽ, được nêu chi tiết trong:
http://openxmldeveloper.org/blog/b/openxmldeveloper/archive/2011/06/13/open-xml-presentation-generation-using-a-template-presentation.aspx
Trong khi đó màn hình-cast khoảng PresentationML, cùng một nguyên tắc áp dụng cho WordprocessingML.
Nhưng thậm chí tốt hơn, với điều kiện bạn đang sử dụng WordprocessingML, là sử dụng các điều khiển nội dung.Đối với một cách tiếp cận tài liệu thế hệ, xem:
http://ericwhite.com/blog/map/generating-open-xml-wordprocessingml-documents-blog-post-series/
Và đối với rất nhiều thông tin về việc sử dụng các điều khiển nội dung nói chung, xem:
http://www.ericwhite.com/blog/content-controls-expanded
-Eric
Thực ra tôi đã thực hiện .ToList(), bởi vì một số biến chứng khác xuất hiện bằng cách sử dụng trước đó dung dịch. Ngoài ra, tôi biết từ tách nó thành nhiều lần chạy (đây, đây là ví dụ xấu), vì vậy trình giữ chỗ của tôi không có '_'. Và trình giữ chỗ của tôi được mã hóa cứng, vì vậy mặc dù tôi biết về các lợi thế của Kiểm soát nội dung, tôi không sử dụng chúng vì tôi không biết chúng đủ tốt và có lịch trình dự án ngắn (nhỏ). Cảm ơn câu trả lời, nó rất sâu sắc, đầy đủ hơn. –