Próbuję wymyślić algorytm, który identyfikuje, czy ciąg jest częścią zawartości tekstowej elementu, czy też jest częścią atrybutów elementu.

Na przykład:

  <a class="tag tag-red-dark" href="/keywords?q=PARTOFATTRIBUTE"> Found TEXTCONTENT </a>

Jeśli wykonasz wyrażenie regularne na TEXTCONTENT lub PARTOFATTRIBUTE, możesz uruchomić ten algorytm, aby sprawdzić, czy są one częścią tekstu, czy częścią atrybutów:

    MatchCollection matches = Regex.Matches(html, @"(?i)TEXTCONTENT");
    for (int i = matches.Count-1; i >= 0 ; i--){
      Match m = matches[i];

      int currentIndex = m.Index;
      bool isTextContent = false;
      while (html[currentIndex] != '<'){
        currentIndex--;
        if (html[currentIndex] == '>'){ // text is placed between > and <
          isTextContent = true;
          break;
        }
      }

      if (isTextContent){
        // do something with text content
      }else{
        // do something with attribute
      }
    }

Ale algorytm jest kruchy. Jeśli Twój html wygląda tak:

  <a class="tag tag-red-dark" title="a>b" href="/keywords?q=PARTOFATTRIBUTE"> Found TEXTCONTENT </a>

PARTOFATTRIBUTE zostanie rozpoznany jako tekst, a nie.

Co więcej, możesz również mieć tekst zawierający <, co sprawia, że algorytm pomyśli, że znalazł atrybut:

  <a class="tag tag-red-dark" title="a>b" href="/keywords?q=PARTOFATTRIBUTE"> < Found TEXTCONTENT </a>

Umieszczenie w atrybutach jest prawidłowe. Czy można określić, czy wybrany ciąg jest częścią atrybutów treści tekstowej wyłącznie na podstawie środowiska, w którym się znajduje?

0
Robert Segdewick 19 listopad 2019, 14:00
1
Pomysł: Możesz wprowadzić metodę o nazwie IsValidElement(), a następnie dla każdego tagu początkowego i końcowego sprawdzić, czy element jest poprawny. Jeśli nie jest prawidłowy, poszukaj następnego tagu końcowego. Sugeruję również, abyś najpierw wymyślił pseudokod, a nie sam kod.
 – 
Azhar Khorasany
19 listopad 2019, 14:17
1
Możesz użyć HtmlAgilityPack lub innej biblioteki innej firmy, która analizuje HTML, a następnie sprawdza wszystkie elementy za pomocą niestandardowej logiki walidacji
 – 
Fabjan
19 listopad 2019, 14:23
HTMLAgilityPack jest wyjątkowo powolny w porównaniu do ręcznego chodzenia po html. W moich testach zbudowanie drzewa zajmuje do 50 ms, podczas gdy Regex zajmuje mniej niż 1 ms. Ponadto nie oferuje funkcji prostego zastępowania treści tekstowej. Wystarczy zastąpić Node nowo utworzonym.
 – 
Robert Segdewick
19 listopad 2019, 14:27

1 odpowiedź

HtmlAgilityPack nie jest wolny, nie musisz analizować całej strony tylko tagu A. Ponieważ prawdopodobnie już przeanalizowałeś tagi a w swoim html. Po prostu podaj tylko ten kod HTML, który potrzebujesz przeanalizować.

        HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
        htmlDoc.LoadHtml("<a class=\"tag tag - red - dark\" title=\"a > b\" href=\" / keywords ? q = PARTOFATTRIBUTE\"> < Found TEXTCONTENT </a>");

        if (htmlDoc.DocumentNode.ChildNodes[0].InnerHtml.Contains("TEXTCONTENT"))
        {
            // do something with text content
        }

        if (htmlDoc.DocumentNode.ChildNodes[0].Attributes["href"].Value.Contains("PARTOFATTRIBUTE"))
        {
            // do something with attribute
        }
0
EJD 19 listopad 2019, 21:47