【问题标题】:Using C#, how can I manually validate a html tag?使用 C#,如何手动验证 html 标签?
【发布时间】:2011-04-22 19:25:43
【问题描述】:

例如,我有这个图像标签:

<img src="http://... .jpg" al="myImage" hhh="aaa" />

例如,对于一般图像标记,我保留所有有效属性的列表

L1=(alt, src, width, height, align, border, hspace, longdesc, vpace)

我正在解析 img 标签,我得到了这样的使用属性:

L2=(src, al, hhh)

如何以编程方式验证图像标签?所以'al'属性应该变成'alt'('alt'属性比'align'更像包含更多字符)并且'hhh'标签会消失(因为没有属性可以像它)?

对于结果,标签应如下所示:

<img src="http://... .jpg" alt="myImage" />

谢谢。

杰夫

【问题讨论】:

  • 假设是 XHTML,但我认为这个问题对于 HTML 也应该足够好。

标签: c# html parsing validation


【解决方案1】:

您可以使用 Linq2Xml 轻松解析代码:

XElement doc = XElement.Parse(...)

然后使用最佳匹配算法对内存中的有效属性字典更正错误的属性。

编辑:我编写并测试了这个简化的最佳匹配算法(对不起,它是 VB):

Dim validTags() As String =
            {
                "width",
                "height",
                "img"
            }

(简化,您应该创建一个更结构化的字典,其中包含标签和每个标签的可能属性)

Dim maxMatch As Integer = 0
Dim matchedTag As String = Nothing
For Each Tag As String In validTags
    Dim match As Integer = checkMatch(Tag, source)
    If match > maxMatch Then
        maxMatch = match
        matchedTag = Tag
    End If
Next

Debug.WriteLine("matched tag {0} matched % {1}", matchedTag, maxMatch)

上面的代码调用了一个方法来确定源字符串等于任何有效标签的百分比。

Private Function checkMatch(ByVal tag As String, ByVal source As String) As Integer

        If tag = source Then Return 100


        Dim maxPercentage As Integer = 0

        For index As Integer = 0 To tag.Length - 1

            Dim tIndex As Integer = index
            Dim sIndex As Integer = 0
            Dim matchCounter As Integer = 0

            While True
                If tag(tIndex) = source(sIndex) Then
                    matchCounter += 1
                End If

                tIndex += 1
                sIndex += 1

                If tIndex + 1 > tag.Length OrElse sIndex + 1 > source.Length Then
                    Exit While
                End If
            End While

            Dim percentage As Integer = CInt(matchCounter * 100 / Math.Max(tag.Length, source.Length))
            If percentage > maxPercentage Then maxPercentage = percentage
        Next

        Return maxPercentage

    End Function

上面的方法,给定一个源字符串和一个标签,找到比较单个字符的最佳匹配百分比。

给定“widt”作为输入,它找到“width”作为匹配值达到 80% 的最佳匹配。

【讨论】:

  • 是的,您根据有效标签列表检查每个找到的标签,以及每个标签的每个属性元素;如果标签/属性名称不在有效标签列表中,则计算它们不同的字符,即:“widt”与“width”不同,但匹配率为 80%,因此您可以更正它。
  • 你能给我一个这个算法的例子吗?谢谢。
  • 我已经在 c# 中实现了你的算法,但是如果我有 'scr' 而不是 'src' 它会给我 33% 的匹配度,如果我有 'sr' 而不是 'src' 它会给我66% 匹配...我认为最好的情况是购买的 66%。我不明白为什么如果我在单词中间省略了一个字符(或者说错了),结果会小于 50%...
  • 为 scr 提供 33% 是正确的:您只提供了 1/3 正确的字符,只提供了“s”。算法不检查相同字符的排列,我认为这是正确的。左比赛应该感觉到吗?我不这么认为,它们是不相关的词,即使它是另一个词的变位词。我认为 sr->src 也是正确的,一个词是正确的 2/3。当您在源代码中间省略一个字母时,您所说的情况不同:我的算法按顺序比较字母,因此如果您有例如“middle”和“mixdle”,您会从 6 个匹配的字母中得到 5 个,这是正确的.但如果你省略了一个字母...
  • ...然后比较就爆炸了。使用 sanity->saity 你会得到 6 分中的 2 分,因为丢失的字母会扰乱所有内容。如果你想要一个更好的算法,你可以改变它并尝试强制这两个词的长度相同。即:sanity->saity 会在较短的单词中添加一个字母,在不同的位置:Xsaity、sXaity、saXity、saiXity、saitXy、saityX。最佳匹配女巫 saXity yuo 得到 6 分中的 5 分 :)
【解决方案2】:

标签的解析是最难的部分,既然你已经这样做了,你现在要做的就是循环遍历元素,检查它们是否与一组有效的元素相匹配,如果它们无效则检查它们针对一系列常见拼写错误的项目,并根据需要替换/删除。

类似于:

String[] ValidItems = {"alt", "src", "width", "height", "align", "border", "hspace", "longdesc", "vpace"};

Dictionary<String, String> MispeltItems = { {"al", "alt" } };

for(int i = ImgTagAttributes-1; i >= 0; i--)
{
    var element = ImgTagAttributes[i];
    if(!ValidItems.Contains(element))
    {
        if(MispeltItems.ContainsKey(element))
        {
            ImgTagElements.Replace(element, MispeltItems[element].Value);
            //Or use remove and insert.
        }
        else
        {
            ImgTagElements.RemoveAt(i);
        }
    }
}

(写在堆栈溢出中,如果有任何错误就说,只是为了让你有一个基本的想法)

【讨论】:

  • 如果我有一个包含 26000 行的 html 文件?在 html 中使用所有不同的标签?
  • 你说你有一个有效属性列表,所以可以用 Dictionary 来完成,其中第一个元素是标签,第二个是有效属性.由于歧义(例如,al 可能是 alt 或 align),如果没有拼写错误的项目列表,就无法真正自动获取拼写错误的项目。将它们转换成 c# 格式完全是另一回事,你说得还不够多,所以我暂时忽略它。
猜你喜欢
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
相关资源
最近更新 更多