【问题标题】:How to prevent duplicate text value output by XElement.DescendantNodes()?如何防止 XElement.DescendantNodes() 输出重复的文本值?
【发布时间】:2016-09-12 13:14:42
【问题描述】:

问题:XElement.DescendantNodes() 似乎将某些部分输出两次。

背景:

我需要将<body> 元素的全部内容复制到具有嵌入样式的<div> 内的新html 文档中。这适用于 html 邮件,其中嵌入样式应该比样式块更好,因为许多邮件代理会剥离 <head> 部分。但是,我遇到了两次获得一些零件的麻烦。如何解决这个问题?

这里是示例输入:

<body>
  some text
  <a href="http://www.nix.com/index.html">Click Me</a>
  <br />
  <span>more text</span>
</body>

这是带有重复字符串的输出,否则正是我需要的:

<body>
  <div style="font-family: Verdana; font-size: 12px;">
    some text
    <a href="http://www.nix.com/index.html">Click Me</a>
    Click Me           <<<===duplicate!!!
    <br />
    <span>more text</span>
    more text           <<<===duplicate!!!
  </div>
</body>

这是代码,我希望DescendantNodes() 应该是提取像&lt;a&gt; 这样的xelement 节点和像“一些文本”这样的文本节点的正确方法:

        using System.Xml.Linq;//XElement

        XElement InputMail = 
            new XElement("body",
                "some text",
                new XElement("a",
                    new XAttribute("href", "http://www.nix.com/index.html"),
                    "Click Me"),
                new XElement("br"),
                new XElement("span", "more text"));

        XElement OutputMail =
            new XElement("body",
                new XElement("div",
                   new XAttribute("style", "font-family: Verdana; font-size: 12px;"),
                   InputMail.DescendantNodes()));

【问题讨论】:

    标签: c# html xelement


    【解决方案1】:

    DescendantNodes 将返回真正的所有节点,包括子节点、孙节点等。这就是为什么你会看到重复的原因——最内层的节点作为它们各自父节点的一部分返回,加上它们本身。您只需要直接子节点,为此您可以使用:

    XElement OutputMail =
          new XElement("body",
              new XElement("div",
                 new XAttribute("style", "font-family: Verdana; font-size: 12px;"),
                 InputMail.Nodes()));
    

    【讨论】:

    • 我仍然不明白故意退货两次有什么用,但这确实比我想象的更快地解决了我的问题。太好了!
    • 您可以在某些(相当有限的)情况下使用 DescendantNodes,例如,如果您想在 xml 中查找所有注释节点。请参见此处 - 例如stackoverflow.com/a/9851414/5311735
    【解决方案2】:

    在VB中我会这样做

        outp.<div>.FirstOrDefault.Add(inp.Nodes)
    

    这些声明

        Dim inp As XElement = <body>
                                  some text
                                  <a href="http://www.nix.com/index.html">Click Me</a>
                                  <br/>
                                  <span>more text</span>
                              </body>
    
        Dim outp As XElement = <body>
                                   <div style="font-family: Verdana; font-size: 12px;">
    
                                   </div>
                               </body>
    

    【讨论】:

    • 实际解决方法和上一个一样:使用Nodes属性代替DescendantNodes即可。新是 .&lt;div&gt; 的把戏,我以前没见过,以后肯定会在 C# 中尝试一下。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 2023-01-08
    • 2019-11-12
    • 2015-12-31
    • 2010-10-21
    • 2017-12-25
    相关资源
    最近更新 更多