【问题标题】:changing a node type to #text whilst keeping the innernodes with the HtmlAgilityPack将节点类型更改为#text,同时使用 HtmlAgilityPack 保留内部节点
【发布时间】:2010-05-17 14:00:05
【问题描述】:

我正在使用 HtmlAgilityPack 来解析我正在转换为 HTML 的 XML 文件。一些节点将被转换为 HTML 等价物。其他不必要的我需要在保留内容的同时删除。我尝试将其转换为 #text 节点,但没有成功。这是我的代码:

private HtmlNode ConvertElementsPerDatabase(HtmlNode parentNode, bool transformChildNodes)
{
    var listTagsToReplace = XmlTagMapping.SelectAll(string.Empty);  // Custom Dataobject
    var node = parentNode;
    if (node != null)
    {
        var bNodeFound = false;
        if (node.Name.Equals("xref"))
        {
            bNodeFound = true;
            node = NodeXref(node);
        }
        if (node.Name.Equals("graphic"))
        {
            bNodeFound = true;
            node = NodeGraphic(node);
        }
        if (node.Name.Equals("ext-link"))
        {
            bNodeFound = true;
            node = NodeExtLink(node);
        }

        foreach (var infoTagToReplace in listTagsToReplace)
        {
            if (node.Name.Equals(infoTagToReplace.XmlTag))
            {
                bNodeFound = true;
                node.Name = infoTagToReplace.HtmlTag;
                if (!string.IsNullOrEmpty(infoTagToReplace.CssClass))
                    node.Attributes.Add("class", infoTagToReplace.CssClass);

                if (node.HasAttributes)
                {
                    var listTagAttributeToReplace = XmlTagAttributeMapping.SelectAll_TagId(infoTagToReplace.Id); // Custom Dataobject
                    for (int i = 0; i < node.Attributes.Count; i++ )
                    {
                        var bDeleteAttribute = true;
                        foreach (var infoTagAttributeToReplace in listTagAttributeToReplace)
                        {
                            if (infoTagAttributeToReplace.XmlName.Equals(node.Attributes[i].Name))
                            {
                                node.Attributes[i].Name = infoTagAttributeToReplace.HtmlName;
                                bDeleteAttribute = false;
                            }
                        }
                        if (bDeleteAttribute)
                            node.Attributes.Remove(node.Attributes[i].Name);
                    }
                }
            }
        }
        if (transformChildNodes)
            for (int i = 0; i < parentNode.ChildNodes.Count; i++)
                parentNode.ChildNodes[i] = ConvertElementsPerDatabase(parentNode.ChildNodes[i], true);

        if (!bNodeFound)
        {
            // Replace with #text
        }
    }
    return parentNode;
}

最后,如果找不到节点,我需要进行节点替换(您会看到“替换为#text”注释)。我整天都在扯我的头发(剩下的),这可能很愚蠢。我无法获得编译帮助,也没有在线版本。帮助 Stackoverflow!你是我唯一的希望。 ;-)

【问题讨论】:

  • 我的回答显然是错误的 - 当我无法同时看到开始和结束时,跟踪所有范围块太难了......:P 不管怎样,有两个新问题: 1)你真的应该给parentNode.ChildNodes[i]递归的值,还是应该把它给其他变量,例如node? 2) 为什么返回parentNode 而不是node

标签: c# .net html html-agility-pack


【解决方案1】:

我认为你可以这样做:

return new HtmlNode(HtmlNodeType.Text, parentNode.OwnerDocument, 0);

这当然会将节点添加到文档的开头,但我假设您有某种代码来处理应在文档中添加节点的位置。

关于文档注释,Html Agility Pack documentation 的当前(截至撰写本文时)下载包含一个不需要编译即可查看的 CHM 文件。

【讨论】:

  • 是的,我明白了……不幸的是,里面的所有页面都说“找不到文件”……虽然有一个索引……
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 2013-01-11
  • 2011-04-18
相关资源
最近更新 更多