none
Open XML - Remove paragraph RRS feed

  • Question

  • I have this function from Eric White site (http://ericwhite.com/blog/map/generating-open-xml-wordprocessingml-documents-blog-post-series/). It works almost perfect for my need except that i need to change the replace operation for SelectValue. If the new replace value is empty (not found) and the SelectValue tag is the only element in the paragraph then i want to have that paragraph removed.

    Can someone help?

    The original code is like this:

    static object Transform(XNode node, XElement document)
    {
            XElement element = node as XElement;
            if (element != null)
            {
                if (element.Name == w + "sdt")
                {
                    string tag = element.Elements(w + "sdtPr")
                        .Elements(w + "alias")
                        .Attributes(w + "val")
                        .FirstOrDefault()
                        .Value;
                    if (tag == "Config") return null;
                    if (tag == "SelectValue")
                    {
                        XElement run = element.Element(w + "sdtContent").Element(w + "r");
                        var rr = element.Element(w + "sdtContent");
                        string valueSelector = GetContentControlContents(element);
                        string newValue = document.XPathSelectElement(valueSelector).Value;
                        var newElement = new XElement(w + "r",
                            run.Elements().Where(e => e.Name != w + "t"),
                            new XElement(w + "t", newValue));
                        return (newElement);
                    }
                    if (tag == "Table")
                    {
                        XElement content = GetContentControlByTag(element, "Content");
                        XElement selectRowsContentControl =
                            GetContentControlByTag(element, "SelectRows");
                        string selector = GetContentControlContents(selectRowsContentControl);
                        var tableData = document.XPathSelectElements(selector);
                        XElement table = content.Descendants(w + "tbl").FirstOrDefault();
                        XElement protoRow = table.Elements(w + "tr").Skip(1).FirstOrDefault();
                        XElement newTable = new XElement(w + "tbl",
                            table.Elements().Where(e => e.Name != w + "tr"),
                            table.Elements(w + "tr").FirstOrDefault(),
                            tableData.Select(d =>
                                new XElement(w + "tr",
                                    protoRow.Elements().Where(r => r.Name != w + "tc"),
                                    protoRow.Elements(w + "tc")
                                        .Select(tc =>
                                        {
                                            XElement paragraph = tc.Elements(w + "p")
                                                .FirstOrDefault();
                                            XElement run = paragraph.Elements(w + "r")
                                                .FirstOrDefault();
                                            string cellSelector = paragraph.Value;
                                            string cellData =
                                                d.XPathSelectElement(cellSelector).Value;
                                            XElement newCell = new XElement(w + "tc",
                                                tc.Elements().Where(z => z.Name != w + "p"),
                                                new XElement(w + "p",
                                                    paragraph.Elements().Where(z1 => z1.Name != w + "r"),
                                                    new XElement(w + "r",
                                                        run.Elements().Where(z2 => z2.Name != w + "t"),
                                                        new XElement(w + "t", cellData))));
                                            return newCell;
                                        }))));
                        return newTable;
                    }
                    if (tag == "Conditional")
                    {
                        XElement selectTestValueContentControl =
                            GetContentControlByTag(element, "SelectTestValue");
                        string selectTestValue =
                            GetContentControlContents(selectTestValueContentControl);
                        string match = GetContentControlContents(
                            GetContentControlByTag(element, "Match"));
                        XElement contentContentControl =
                            GetContentControlByTag(element, "Content");
                        string value =
                            document.XPathSelectElement(selectTestValue).Value;
                        if (value == match)
                        {
                            var content = contentContentControl.Element(w + "sdtContent")
                                .Elements().Select(e => Transform(e, document));
                            return content;
                        }
                        else
                            return null;
                    }
                }
                return new XElement(element.Name,
                    element.Attributes(),
                    element.Nodes().Select(n => Transform(n, document)));
            }
            return node;
    }

    The part of code that i need to change is this:

    if (tag == "SelectValue")
    {
    	XElement run = element.Element(w + "sdtContent").Element(w + "r");
    	var rr = element.Element(w + "sdtContent");
    	string valueSelector = GetContentControlContents(element);
    	string newValue = document.XPathSelectElement(valueSelector).Value;
    	var newElement = new XElement(w + "r",
    		run.Elements().Where(e => e.Name != w + "t"),
    		new XElement(w + "t", newValue));
    	return (newElement);
    }
    I've tried inserting this line of code but it didn't work:
    string newValue = valueElement == null ? string.Empty : datasource.XPathSelectElement(valueSelector).Value;
    if (string.IsNullOrEmpty(newValue)) return null;

    Tuesday, October 16, 2012 6:02 AM

Answers

  • Hi Syslock,

    Thanks for posting in the MSDN Forum.

    I found that in your code snippet you use System.Xml namespace to handle Word document. It’s quite complex for people to handle Open XML document’s issue. As us discussed in this forum we can handle document use Open Xml SDK. Open Xml SDK warp Open Xml format into all kind of classes, it will let your work become easier. For example as the subject for this thread, we can use following snippet

    if you want to remove the paragraph form the document:

                using (WordprocessingDocument WPD = WordprocessingDocument
                    .Open(OriginalPath, true))
                {
                    MainDocumentPart MDP = WPD.MainDocumentPart;
                    Document D = MDP.Document;
                    foreach (Paragraph P in D.Descendants<Paragraph>())
                    {
                        foreach (Run R in P.Descendants<Run>())
                        {
                            if (R.Descendants<Text>()
                                .Where(T => T.Text == "Paragraph 2").Count() > 0)
                            {
                                SetLog(P.InnerText, OXULogType.INFO);
                                P.Remove();
                            }
                        }
                    }
                    D.Save();
                }

    I hope it can help you.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, October 17, 2012 6:06 AM
    Moderator