Erreur du pack d'agilité HTMl lors de l'analyse et du renvoi de XElement

.net-3.5 c# html-agility-pack html-parsing

Question

Je peux analyser le document et générer une sortie. Toutefois, la sortie ne peut pas être analysée dans un XElement à cause d'une balise ap. Tout le reste de la chaîne est analysé correctement.

Mon entrée:

var input = "<p> Not sure why is is null for some wierd reason!<br><br>I have implemented the auto save feature, but does it really work after 100s?<br></p> <p> <i>Autosave?? </i> </p> <p>we are talking...</p><p></p><hr><p><br class=\"GENTICS_ephemera\"></p>";

Mon code:

var input = "<p> Not sure why is is null for some wierd reason!<br><br>I have implemented the auto save feature, but does it really work after 100s?<br></p> <p> <i>Autosave?? </i> </p> <p>we are talking...</p><p></p><hr><p><br class=\"GENTICS_ephemera\"></p>";

Ma sortie:

var input = "<p> Not sure why is is null for some wierd reason!<br><br>I have implemented the auto save feature, but does it really work after 100s?<br></p> <p> <i>Autosave?? </i> </p> <p>we are talking...</p><p></p><hr><p><br class=\"GENTICS_ephemera\"></p>";

La balise p en gras est celle qui n’a pas été sortie correctement ... Y at-il un moyen de contourner cela? Est-ce que je fais quelque chose de mal avec le code?

Réponse acceptée

Ce que vous essayez de faire est essentiellement de transformer une entrée HTML en une sortie XML.

Html Agility Pack peut le faire lorsque vous utilisez l'option OptionOutputAsXml , mais dans ce cas, vous ne devez pas utiliser la propriété InnerHtml, mais laissez plutôt le pack Agility Html travailler pour vous, avec l'une des méthodes de Save de HtmlDocument.

Voici une fonction générique pour convertir un texte HTML en une instance de XElement:

public static XElement HtmlToXElement(string html)
{
    if (html == null)
        throw new ArgumentNullException("html");

    HtmlDocument doc = new HtmlDocument();
    doc.OptionOutputAsXml = true;
    doc.LoadHtml(html);
    using (StringWriter writer = new StringWriter())
    {
        doc.Save(writer);
        using (StringReader reader = new StringReader(writer.ToString()))
        {
            return XElement.Load(reader);
        }
    }
}

Comme vous le voyez, vous n’avez pas à faire beaucoup de travail par vous-même! Veuillez noter que, puisque votre texte d'entrée d'origine ne comporte pas d'élément racine, le pack d'agilité HTML ajoute automatiquement un SPAN englobant pour garantir que la sortie est valide au format Xml.

Dans votre cas, vous souhaitez également traiter certaines balises, voici comment procéder avec votre exemple:

public static XElement HtmlToXElement(string html)
{
    if (html == null)
        throw new ArgumentNullException("html");

    HtmlDocument doc = new HtmlDocument();
    doc.OptionOutputAsXml = true;
    doc.LoadHtml(html);
    using (StringWriter writer = new StringWriter())
    {
        doc.Save(writer);
        using (StringReader reader = new StringReader(writer.ToString()))
        {
            return XElement.Load(reader);
        }
    }
}

Comme vous le voyez, vous ne devez pas utiliser de fonction chaîne brute, mais plutôt utiliser les fonctions DOM Html Agility Pack (SelectNodes, Add, Remove, etc ...).


Réponse populaire

Si vous consultez les commentaires sur la documentation pour OptionFixNestedTags vous verrez ce qui suit:

//     Defines if LI, TR, TH, TD tags must be partially fixed when nesting errors
//     are detected. Default is false.

Donc, je ne pense pas que cela vous aidera avec les balises p HTML non fermées. Selon une vieille bibliothèque SO de questions C # pour nettoyer le code HTML, HTML Tidy pourrait fonctionner à cet effet.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi