WordprocessingDocument分隔文本(不必要)

时间:2013-06-27 06:09:24

标签: c# xml formatting wordprocessingml word-processor

我正在尝试替换word文档中的某些位置,这些位置充当模板。这些地方标记为以@开头的字词。例如@Name。我选择所有文本,用我的功能运行它们并替换。这背后的所有逻辑都很好。但是,由于我不知道的原因,文本的定义简单如下:

List<Text> texts = w.MainDocumentPart.Document.Descendants<Text>().ToList();

不是我期望的那样。例如(文本的简短列表,每行中有一个文本):

Document date: 
@
date
, written by: 
@Name 
@
Surname

即使它应该在一行中:Document date: @date, written by: @Name @Surname。如您所见,在@date@Surname的情况下,我无法正确使用我的替换方法,因为没有{{1} } @date积极到位。所以我改进了我的代码,但是现在我发现了很多缺陷,所以它将剩下的@Surname连接到下一个文本。不幸的是,我在一张表中找到了一个完全杀死我所有算法的文本。 就像这样:

@

即使我没有特别用不同风格格式化它。所以你可以看到,它必须是(@ sum_ words) ,在这种情况下,我的算法很容易被替换。不幸的是,我无法做到。因此,我的问题是:

  1. 为什么即使我没有制作零件也要分成几部分 这个词有什么不同吗?
  2. 有没有办法解决这个问题,所以我的 文本可以完整吗?
  3. 更新

    到目前为止我能做的最好的事情是:

    (@sum_words)

    如果文本被中途分割,则将文本连接起来(从我看到的文本中,它们只会根据我的需要for (int i = texts.Count - 1; i > 0; i--) { if (texts[i - 1].Text.EndsWith("@") || texts[i - 1].Text.EndsWith("_")) { texts[i - 1].Text = texts[i - 1].Text + texts[i].Text; texts[i].Text = ""; } } @分开。循环被反转因为保存组中第一个文本部分的属性而不是最后一个(例如保留元素之前的间距)更有意义。

    更新2

    这是请求的表格单元格:

    _

1 个答案:

答案 0 :(得分:1)

我在WordML文档中替换变量的唯一问题是由拼写和语法模块引起的,这些模块倾向于插入特殊标记,这些标记会破坏您的变量名称,这可以通过在模板中停用Word中的语法错误来完全停用来解决编辑。

我的替换方法是这样的(我的命名变量的约定有点不同,这个会被添加到你的):

public static void Assign(XElement xe, string name, string value)
{
    XElement el = xe.Descendants()
        .FirstOrDefault(e => e.Name.LocalName == "t" && e.Value.Contains("(@" + name + ")"));
    if (el != null)
    {
        el.Value = el.Value.Replace("(@" + name + ")", value);
    }
    else
    {
        AssignFallback(xe, name, value);
    }   
}

编辑2

我写了一个替换变量的后备方法,以防上面的内容不起作用(case el == null)。段落w:p可以包含多个运行,并且我们的变量名称可以在连续的运行系列中被分解。因此,我们希望识别这些并仅在第一个值中替换值,而删除其余值。我们必须小心保存在变量名称之后和之后出现的文本(前缀将在第一次运行中,而前一次将在最后一次运行中)。

public static void AssignFallback(XElement xe, string name, string value)
{
    string varName = "(@" + name + ")";
    XElement xep = xe.Descendants()
            .FirstOrDefault(x => x.Name.LocalName == "p" && x.Value.Contains(varName));
    if (xep == null)
    {
        return;
    }
    string prefix = "", sufix = "";
    List<XElement> truns = new List<XElement>();
    List<XElement> allruns = xep.Descendants().Where(x => x.Name.LocalName == "r").ToList();
    for (int i = 0; i < allruns.Count; i++)
    {
        if (!allruns[i].Value.Contains("(@"))
        {
            continue;
        }
        int index = allruns[i].Value.IndexOf("(@");
        prefix = allruns[i].Value.Substring(0, index);
        truns.Clear();
        truns.Add(allruns[i]);
        string nameTemp = allruns[i].Value.Substring(index, allruns[i].Value.Length - index);
        if (!varName.StartsWith(nameTemp))
        {
            continue;
        }
        for (int j = i + 1; j < allruns.Count; j++)
        {
            nameTemp += allruns[j].Value;
            truns.Add(allruns[j]);
            if (nameTemp.StartsWith(varName))
            {
                sufix = nameTemp.Substring(varName.Length);
                break;
            }
            else if (nameTemp.Length > varName.Length)
            {
                break;
            }
        }
        if (nameTemp.StartsWith(varName))
        {
            XElement xet = truns[0].Descendants().FirstOrDefault(x => x.Name.LocalName == "t");
            xet.Value = prefix + value + sufix;
            for (int j = 1; j < truns.Count; j++)
            {
                truns[j].Remove();
            }
        }
    }
}