【问题标题】:Modifying InnerXml of a text XmlNode修改文本 XmlNode 的 InnerXml
【发布时间】:2011-12-15 16:40:34
【问题描述】:

我用 SGML 和 XmlDocument 遍历一个 html 文档。当我找到一个类型为 Text 的 XmlNode 时,我需要更改其具有 xml 元素的值。我无法更改 InnerXml,因为它是只读的。我试图更改 InnerText,但这次标签描述符字符 <> 编码为 <>。例如:

<p>
    This is a text that will be highlighted.
    <anothertag />
    <......>
</p>

我正在尝试更改为:

<p>
    This is a text that will be <span class="highlighted">highlighted</span>.
    <anothertag />
    <......>
</p>

修改文本 XmlNode 值的最简单方法是什么?

【问题讨论】:

    标签: c# xml-parsing xmldocument sgmlreader


    【解决方案1】:

    我有一个解决方法,我不知道它是一个真正的解决方案还是什么,但它可以产生我想要的结果。请评论此代码是否值得解决

        private void traverse(ref XmlNode node)
        {
            XmlNode prevOldElement = null;
            XmlNode prevNewElement = null;
            var element = node.FirstChild;
            do
            {
                if (prevNewElement != null && prevOldElement != null)
                {
                    prevOldElement.ParentNode.ReplaceChild(prevNewElement, prevOldElement);
                    prevNewElement = null;
                    prevOldElement = null;
                }
                if (element.NodeType == XmlNodeType.Text)
                {
                    var el = doc.CreateElement("text");
                    //Here is manuplation of the InnerXml.
                    el.InnerXml = element.Value.Replace(a_search_term, "<b>" + a_search_term + "</b>");
                    //I don't replace element right now, because element.NextSibling will be null.
                    //So I replace the new element after getting the next sibling.
                    prevNewElement = el;
                    prevOldElement = element;
                }
                else if (element.HasChildNodes)
                    traverse(ref element);
            }
            while ((element = element.NextSibling) != null);
            if (prevNewElement != null && prevOldElement != null)
            {
                prevOldElement.ParentNode.ReplaceChild(prevNewElement, prevOldElement);
            }
    
        }
    

    另外,我在遍历函数之后删除了&lt;text&gt;&lt;/text&gt; 字符串:

            doc = new XmlDocument();
            doc.PreserveWhitespace = true;
            doc.XmlResolver = null;
            doc.Load(sgmlReader);
            var html = doc.FirstChild;
            traverse(ref html);
            textBox1.Text = doc.OuterXml.Replace("<text>", String.Empty).Replace("</text>", String.Empty);
    

    【讨论】:

      【解决方案2】:
      using System;
      using System.Xml;
      
      public class Sample {
      
        public static void Main() {
          XmlDocument doc = new XmlDocument();
          doc.LoadXml(
          "<p>" +
          "This is a text that will be highlighted." +
          "<br />" +
          "<img />" +
          "</p>");
          string ImpossibleMark = "_*_";
          XmlNode elem = doc.DocumentElement.FirstChild;
          string thewWord ="highlighted";
          if(elem.NodeType == XmlNodeType.Text){
              string OriginalXml = elem.ParentNode.InnerXml;
              while(OriginalXml.Contains(ImpossibleMark)) ImpossibleMark += ImpossibleMark;
              elem.InnerText = elem.InnerText.Replace(thewWord, ImpossibleMark);
              string replaceString = "<span class=\"highlighted\">" + thewWord + "</span>";
              elem.ParentNode.InnerXml = elem.ParentNode.InnerXml.Replace(ImpossibleMark, replaceString);
          }
      
          Console.WriteLine(doc.DocumentElement.InnerXml);
        }
      }
      

      【讨论】:

      • 如果 InnerXML 有一个名为“highlighted”的标签,或者如果搜索词是像 span 这样的标签名称,您的解决方案将不起作用。实际上我也不直接替换文本。我将text 拆分为单词。我有一个库,可以为我提供词干,我遍历text 中的每个单词并完成词干工作。所以我只需要处理文本节点。还是谢谢。
      • 正如肯定所说的那样。所以,我有一点修改。我认为这在大多数情况下就足够了。
      • 严格来说,可能没用,我认为在这种情况下你的方式。简化的方法比我可能不会的要好。
      【解决方案3】:

      InnerText property 将为您提供XmlNode 的所有子节点的文本内容。您真正要设置的是InnerXml property,它将被解释为 XML,而不是文本。

      【讨论】:

      • 是的,谢谢,但如果 XmlNode 的类型是 Text,则 InnerXml 属性是只读的。我需要另一个解决方案。
      猜你喜欢
      • 2014-07-18
      • 2016-12-23
      • 1970-01-01
      • 2017-08-27
      • 2011-12-14
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多