2009-10-03 10 views
28

Je suis à la recherche d'un analyseur CSS en Java. En particulier, mon exigence est, pour un nœud/élément donné dans un document HTML, de pouvoir demander/obtenir les styles css pour cet élément à partir de l'analyseur.Vous cherchez un analyseur CSS en Java

Je sais qu'il y a l'interface SAC du W3C et une ou deux implémentations basées sur cela - mais les turlurgies/exemples semblent inexistants.

Toute aide/points dans la bonne direction très appréciée.

Merci

+5

Jetez un oeil à - http://cssparser.sourceforge.net/ – adatapost

+1

@adatapost: reposter votre réponse comme une « réponse » au lieu d'un « commentaire » –

Répondre

4

un ajout à cssparser.sourcefourge.net,

Cobra:

http://lobobrowser.org/cobra.jsp

+0

grand merci je vais vérifier –

+0

utilise également l'ancien projet CSSParser –

16

Je l'ai utilisé CSSParser et je l'aime it- il donne de bons commentaires sur les erreurs que bien.

Voici quelques exemples de code que j'ai trouvé et modifié:

package com.dlogic; 

import com.steadystate.css.parser.CSSOMParser; 
import org.w3c.css.sac.InputSource; 
import org.w3c.dom.css.CSSStyleSheet; 
import org.w3c.dom.css.CSSRuleList; 
import org.w3c.dom.css.CSSRule; 
import org.w3c.dom.css.CSSStyleRule; 
import org.w3c.dom.css.CSSStyleDeclaration; 
import java.io.*; 


public class CSSParserTest 
{ 

    protected static CSSParserTest oParser; 

    public static void main(String[] args) { 

      oParser = new CSSParserTest(); 

      if (oParser.Parse("design.css")) { 

       System.out.println("Parsing completed OK"); 

      } else { 

       System.out.println("Unable to parse CSS"); 

      } 
    } 


    public boolean Parse(String cssfile) 
    { 

     FileOutputStream out = null; 
     PrintStream ps = null; 
     boolean rtn = false; 

     try 
     { 

       // cssfile accessed as a resource, so must be in the pkg (in src dir). 
       InputStream stream = oParser.getClass().getResourceAsStream(cssfile); 

       // overwrites and existing file contents 
       out = new FileOutputStream("log.txt"); 

       if (out != null) 
       { 
        //log file 
        ps = new PrintStream(out); 
        System.setErr(ps); //redirects stderr to the log file as well 

       } else { 

        return rtn; 

       } 


       InputSource source = new InputSource(new InputStreamReader(stream)); 
       CSSOMParser parser = new CSSOMParser(); 
       // parse and create a stylesheet composition 
       CSSStyleSheet stylesheet = parser.parseStyleSheet(source, null, null); 

       //ANY ERRORS IN THE DOM WILL BE SENT TO STDERR HERE!! 
       // now iterate through the dom and inspect. 

       CSSRuleList ruleList = stylesheet.getCssRules(); 

       ps.println("Number of rules: " + ruleList.getLength()); 


       for (int i = 0; i < ruleList.getLength(); i++) 
       { 
       CSSRule rule = ruleList.item(i); 
       if (rule instanceof CSSStyleRule) 
       { 
        CSSStyleRule styleRule=(CSSStyleRule)rule; 
        ps.println("selector:" + i + ": " + styleRule.getSelectorText()); 
        CSSStyleDeclaration styleDeclaration = styleRule.getStyle(); 


        for (int j = 0; j < styleDeclaration.getLength(); j++) 
        { 
          String property = styleDeclaration.item(j); 
          ps.println("property: " + property); 
          ps.println("value: " + styleDeclaration.getPropertyCSSValue(property).getCssText()); 
          ps.println("priority: " + styleDeclaration.getPropertyPriority(property)); 
        } 



        }// end of StyleRule instance test 
       } // end of ruleList loop 

       if (out != null) out.close(); 
       if (stream != null) stream.close(); 
       rtn = true; 
      } 
      catch (IOException ioe) 
      { 
       System.err.println ("IO Error: " + ioe); 
      } 
      catch (Exception e) 
      { 
       System.err.println ("Error: " + e); 

      } 
      finally 
      { 
       if (ps != null) ps.close(); 
      } 

      return rtn; 

    } 

} 
+0

Bonjour Gene, merci pour l'info. J'ai utilisé CSSParser avec pas trop de problèmes - sauf deux petits ennuis: 1) S'il y a une règle non reconnue ou mal formatée, l'analyseur semble apparaître sur l'ensemble du fichier - par opposition à l'abandon de cette règle. Évidemment, avec le css réel, cela arrive beaucoup. Aussi, je pense qu'il y a un bug avec les commentaires: les commentaires sur plusieurs lignes semblent aboutir à ce que tous les css suivants soient supprimés jusqu'au prochain commentaire. avez-vous remarqué cela? –

+0

Salut Richard, je viens de commencer à utiliser CSSParser. Je n'ai pas encore remarqué le problème des commentaires abandonnés - J'essaie de trouver un solution au problème de suppression des hacks IE, pour le moment. Avez-vous une expérience de ce problème vous-même? –

+0

pas vraiment - bien que pourrait être la raison de certains des barfing que je vois. Sans savoir ce que vous faites exactement, je suggère de faire un pré-traitement sur chaque fichier CSS avant d'analyser. Vous pourriez peut-être mettre en place des regex pour les hacks IE et les supprimer? –

11

je besoin d'un Parser CSS pour un projet personnel, mais j'ai trouvé que "CSSParser" était trop fastidieux et inflexible pour travailler avec (mais cela pourrait être juste moi), donc j'ai fini par écrire mon propre analyseur CSS simple mais fonctionnel.

Ne hésitez pas à utiliser si vous voulez :-)

OSBCP CSS Parser

+0

J'ai regardé votre projet rapidement et il semble que votre analyseur soit très puissant et fonctionnel. Je pense sérieusement à l'utiliser dans un de mes projets. Y a-t-il des problèmes que je dois savoir? Aussi, les règles CSS peuvent-elles être modifiées en mémoire, puis sauvegardées à nouveau dans un fichier CSS? Merci. – stepanian

+0

Oui. Il analyse les règles dans une liste de règles, qui peuvent être modifiées puis réécrites dans String/File en utilisant toString(). J'espère que cela répond à votre question. – corgrath

+0

Merci. Je l'utilise d'ailleurs et ça fonctionne parfaitement pour moi. – stepanian

13

Une bibliothèque CSS pour la lecture et l'écriture CSS2 et CSS3 fichiers en Java est ph- de css https://github.com/phax/ph-css Il est basé sur une grammaire JavaCC et prend en charge à la fois CSS2 ainsi que CSS3 et permet en outre d'analyser les attributs de style HTML.

  • Il prend aussi en charge
  • les hacks les plus courants "*", "_" et "$" qui ne sont pas spec Il prend en charge les mathématiques CSS - l'expression
  • le calc() Il prend en charge la règle @page
  • Il prend en charge des requêtes média CSS3
  • Il prend en charge des règles @viewport
  • Il prend en charge les règles de @keyframes
  • Il prend en charge les règles de @supports - tout à fait nouvelle
  • Il prend en charge les règles de @namespace
  • Vous pouvez obtenir des informations de localisation de la source pour les différents éléments (numéro de ligne + colonne pour le début et la fin - à la fois pour la balise, ainsi que pour la construction complète)

Depuis 21 mai 2013 un JDK 1.5 version est également disponible, ce qui le rend plus intéressant pour le développement Android

+1

Je l'ai utilisé, et puisque la question a été posée, elle a bien évolué. Nice API, un visiteur pour aller chercher les éléments dont vous avez besoin, manque juste de documentation (mais les docs d'API sont plutôt sympas). Conseillé. – Martin

+0

C'est un tel gâchis que ce beau projet a une mauvaise documentation. Avec un peu de travail, cela pourrait devenir un projet beaucoup plus populaire. – Gili

+0

Cela me ressemble le meilleur –

1

jStyleParser fournit exactement cette fonctionnalité. Il analyse toutes les feuilles de style référencées et les mappe aux noeuds de l'arborescence DOM.

1

Si vous vous débattez avec CSSParser, car il semble y avoir aucune documentation du tout, et vous voulez peut-être analyser juste une chaîne CSS, comme valeur de paramètre de style, voici mon exemple simple d'utilisation:

import org.junit.Test; 
import org.w3c.css.sac.InputSource; 
import org.w3c.dom.css.CSSRule; 
import org.w3c.dom.css.CSSStyleDeclaration; 
import org.w3c.dom.css.CSSValue; 

import com.steadystate.css.parser.CSSOMParser; 

public class ParseCssTest { 

@Test 
public void testParseStyleDeclaration() throws IOException { 
    String cssSample = "margin-top: 0cm; margin-bottom: 0cm; background: #e6e6e6"; 
    CSSOMParser parser = new CSSOMParser(); 
    CSSStyleDeclaration o = parser.parseStyleDeclaration(new InputSource(new StringReader(cssSample))); 
    assertEquals("margin-top: 0cm; margin-bottom: 0cm; background: rgb(230, 230, 230)", o.toString()); 
    assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").toString()); 
    assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").getCssText()); 
    assertEquals(null, o.getPropertyCSSValue("foo")); 
} 

@Test 
public void testParseARule() throws IOException { 
    String cssSample = "r1 { margin-top: 0cm; margin-bottom: 0cm; background: #e6e6e6 }"; 
    CSSOMParser parser = new CSSOMParser(); 
    CSSRule o = parser.parseRule(new InputSource(new StringReader(cssSample))); 
    assertEquals("r1 { margin-top: 0cm; margin-bottom: 0cm; background: rgb(230, 230, 230) }", o.toString()); 
} 

@Test 
public void parseStyleDeclarationWithAdvancedTests() throws IOException { 
    String cssSample = "margin-top: 0 cm; margin-bottom: 0cm; background: #e6e6e6"; 
    CSSOMParser parser = new CSSOMParser(); 
    CSSStyleDeclaration o = parser.parseStyleDeclaration(new InputSource(new StringReader(cssSample))); 
    assertEquals("margin-top: 0 cm; margin-bottom: 0cm; background: rgb(230, 230, 230)", o.toString()); 

    assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").toString()); 
    assertEquals("0cm", o.getPropertyCSSValue("margin-bottom").getCssText()); 
    assertEquals(CSSValue.CSS_VALUE_LIST, o.getPropertyCSSValue("margin-top").getCssValueType()); 

    assertEquals("0 cm", o.getPropertyCSSValue("margin-top").toString()); 
    assertEquals("0 cm", o.getPropertyCSSValue("margin-top").getCssText()); 
    assertEquals(CSSValue.CSS_VALUE_LIST, o.getPropertyCSSValue("margin-top").getCssValueType()); 
} 
} 

Gros avantage de CSSParser, c'est qu'il est actuellement dans Maven. Donc, si vous cherchez quelque chose de simple et facilement utilisable CSSParser semble être une bonne option. Notes: il fait la conversion automatique pour les couleurs du format hexadécimal au format rgb(), mais ne fournit aucune aide pour les tailles avec des unités, il les voit comme une liste de valeurs! Pas si bon.

1

Je viens de déployer mon propre analyseur CSS Stream pour Java, disponible sur github. Ce qui distingue cet analyseur comprend en dehors:

  • Il est un analyseur de flux, de sorte que le gestionnaire d'analyseur recevra notification de tout nouveau contenu immédiatement après chaque élément a été analysé
  • Support complet pour tous actuellement documenté At-règles
  • classes personnalisées TokenSequence et Token Simplifier les processus sélecteurs de manutention, etc.
  • Facile à utiliser et à comprendre
  • utiles pour la validation ou pour des applications plus avancées
  • Évolutif: conçu pour pouvoir gérer les modifications apportées aux définitions CSS.
Questions connexes