2010-08-18 25 views
0

Je me demande si c'est possible.Utilisez HtmlAgilityPack pour diviser un document

je html comme ceci:

<p> 
    <font face="Georgia"> 
    <b>History</b><br>&nbsp; <br>Two of the polysaccharides used in the manufacture of...</font> 
    <a title="PubMed" href="http://www.www.gov/pubmed/" target="_blank"> 
    <font face="Georgia">) and this web site for new development by...well as Self Affirmed Medical Food GRAS status.&nbsp; 
    </font> 
</p> 

<p> 
    <font face="Georgia">[READMORE]</font> 
</p> 

<p><font face="Georgia"><br><strong>Proprietary Composition</strong><br> 
    <br>The method in which soluble fibres are made into... REST OF ARTICLE... 
</p> 

Oui, il est laid html et il vient d'un WYSIWYG j'ai donc peu de contrôle sur elle.

Ce que je veux faire est de rechercher [READMORE] dans le document, supprimer toutes les balises parent (dans ce cas, le <font> et les <p> balises) et les remplacer par un lien de readmore tout en enveloppant le reste du document dans un géant `... reste de l'article ...

Je suis assez sûr que le HtmlAgilityPack m'aura une partie du chemin, mais j'essaie juste de comprendre par où commencer.

Jusqu'à présent, je suis assez sûr que je dois utiliser htmlDoc.DocumentNode.SelectSingleNode(//p[text()="[READMORE]"]) ou quelque chose. Je ne suis pas trop familier avec XPATH.

Pour mes documents, le readmore peut ou non figurer dans une balise font imbriquée.

De même, dans certains cas, il peut ne pas être du tout une étiquette, mais plutôt à la racine du document. Je peux juste faire une recherche régulière et remplacer dans ce cas et il devrait être simple.

Ma situation idéale serait quelque chose comme ça (pseudocode)

var node = SelectNodeContaining("[READMORE]"). 

node.Replace("link here"); 

node.RestOfDocument().Wrap("<div class='wrapper'"); 

Je sais, je rêve ... mais j'espère que cela est logique.

+0

Avez-vous envisagé de le faire côté client avant l'envoi de la sortie WYSIWYG? –

+0

Ceci est le plus facilement accompli avec XSLT. ajoutez la balise "xslt" et vous obtiendrez de nombreuses bonnes réponses presque instantanément. –

+0

@Dimitre. Merci pour le conseil. Terminé. – Armstrongest

Répondre

3

Voici une solution XSLT:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="p[descendant::text()[. = '[READMORE]']]"> 
    <a href="#ReadmoreWrapper">READMORE</a> 
    <div class="wrapper" id="#ReadmoreWrapper"> 
    <xsl:apply-templates select="following-sibling::node()" mode="copy"/> 
    </div> 
</xsl:template> 

<xsl:template match= 
    "node()[ancestor::p[descendant::text()[. = '[READMORE]']] 
     or 
      preceding::p[descendant::text()[. = '[READMORE]']] 
      ] 
    "/> 

    <xsl:template match="node()|@*" mode="copy"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*" mode="copy"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

lorsque cette transformation est appliquée sur le document XML suivant:

<html> 
<p> 
    <font face="Georgia"> 
    <b>History</b><br/>&#xA0; <br/>Two of the polysaccharides used in the manufacture of...</font> 
    <a title="PubMed" href="http://www.www.gov/pubmed/" target="_blank"/> 
    <font face="Georgia">) and this web site for new development by...well as Self Affirmed Medical Food GRAS status.&#xA0; 
    </font> 
</p> 

<p> 
    <font face="Georgia">[READMORE]</font> 
</p> 

<p><font face="Georgia"><br/><strong>Proprietary Composition</strong><br/> 
    <br/>The method in which soluble fibres are made into... REST OF ARTICLE... 
    </font> 
</p> 

</html> 

le résultat recherché est produit:

<html> 
    <p> 
     <font face="Georgia"><b>History</b><br/> <br/>Two of the polysaccharides used in the manufacture of...</font> 
     <a title="PubMed" href="http://www.www.gov/pubmed/" target="_blank"/> 
     <font face="Georgia">) and this web site for new development by...well as Self Affirmed Medical Food GRAS status. 
    </font> 
    </p> 
    <a href="#ReadmoreWrapper">READMORE</a> 
    <div class="wrapper" id="#ReadmoreWrapper"> 
     <p> 
      <font face="Georgia"><br/><strong>Proprietary Composition</strong><br/><br/>The method in which soluble fibres are made into... REST OF ARTICLE... 
    </font> 
     </p> 
    </div> 
</html> 
+1

Il semble que cela fonctionnerait, mais j'ai des erreurs d'analyse. Il n'aime pas ' ' dans le texte lors de l'analyse en tant que document XML. Est-ce que la même Transformation XSLT peut être faite sur un 'HtmlAgilityPack.HtmlDocument'?" – Armstrongest

+1

Je pensais que HtmlAgilityPack produisait un document XML, si ce n'est pas vrai, vous pourriez convertir son DOM HTML en arbre XML (DOM) par programme. la transformation, j'ai remplacé tout '@nbsp;' et aussi toutes les balises non fermées comme '
' avec '
' et ajouter quelques balises de fin '' .Ce sont probablement ces personnes qui ont un sérialiseur au format XML –

+1

Je l'ai fait comme indiqué ci-dessus et cela fonctionne.Chargez votre document dans un HtmlAgilityPack.HtmlDocument, utilisez l'option pour forcer la sortie à se conformer à XML, enregistrer le document, puis le charger dans un objet .NET XmlDocument standard. De là, vous pouvez exécuter votre XSLT, etc. – ssamuel

0

Si je suis tout de suite, vous pouvez essayer une chose ... que la même chose que nous faisons dans l'envoi de mails HTML personnalisés

  1. Créer un modèle de votre page html avec des contenus statiques.
  2. Ajoutez des identifiants pour le contenu dynamique comme vous l'avez indiqué [ReadMore] ou {ReadmOre} ou quelque chose de similaire.
  3. Lisez maintenant le fichier html modèle ligne par ligne et remplacez les identifiants par le texte souhaité.
  4. Enregistrez maintenant la chaîne entière dans un nouveau fichier html ou faites ce que vous voulez.
+0

C'est le plan. Cependant, si je remplace [Readmore] par un lien et encapsule le reste de l'article à partir de ce point dans une balise div, j'aurai des balises non fermées. Je dois enlever les parents de [readmore] (s'ils existent) et ensuite le faire. Je suis coincé sur une façon cohérente de les enlever. – Armstrongest