2009-10-03 15 views
28

Estoy buscando un analizador de CSS en Java. En particular, mi requisito es, para un nodo/elemento dado en un documento HTML, poder preguntar/obtener los estilos CSS para ese elemento del analizador.Buscando un analizador de CSS en java

Sé que hay una interfaz W3C SAC y una o dos implementaciones basadas en esto, pero las tormentas/ejemplos parecen inexistentes.

Cualquier ayuda/puntos en la dirección correcta muy apreciada.

Gracias

+5

Ven a ver - http://cssparser.sourceforge.net/ – adatapost

+1

@adatapost: volver a publicar su respuesta como una "respuesta" en lugar de un "comentario" –

Respuesta

4

una adición a cssparser.sourcefourge.net,

Cobra:

http://lobobrowser.org/cobra.jsp

+0

grandes gracias Voy a comprobar hacia fuera –

+0

utiliza también el viejo proyecto CSSParser –

16

He usado CSSParser y me gusta IT da buenos comentarios sobre los errores como bien.

He aquí algunos ejemplos de código que he encontrado y modificado:

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

Hola Gene, gracias por la información. He estado usando CSSParser sin demasiados problemas, excepto dos pequeñas molestias: 1) Si hay una regla no reconocida o mal formateada, el analizador parece no funcionar en todo el archivo, en lugar de descartar esa regla. Obviamente, con CSS real, esto sucede bastante. Además, creo que hay un error con los comentarios: los comentarios de varias líneas parecen dar como resultado que todos los CSS subsiguientes se eliminen hasta el siguiente comentario. ¿Has notado esto? –

+0

Hola, Richard, acabo de empezar a utilizar CSSParser. Todavía no he notado el problema de los comentarios caídos. Estoy intentando encontrar un solution al problema de que elimina los hacks de IE, por el momento. ¿Tienes alguna experiencia con este tema? –

+0

no realmente, aunque podría ser la razón de algunas de las barfing que veo. Sin saber lo que estás haciendo exactamente, te sugiero que hagas un preprocesamiento en cada archivo css antes de analizar. ¿Podría quizás configurar algunas expresiones regulares para los hacks de IE y eliminarlas? –

11

necesitaba una Analizador de CSS para un proyecto propio, pero encontré que "CSSParser" era demasiado tedioso e inflexible para trabajar (pero podría haber sido solo yo), así que terminé escribiendo mi propio analizador de CSS simple pero funcional.

Siéntase libre de usarlo si quieres :-)

OSBCP CSS Parser

+0

Miré su proyecto rápidamente y parece que su analizador es muy potente y funcional. Estoy pensando seriamente en usarlo en uno de mis proyectos. ¿Hay algún problema que necesite saber? Además, ¿las reglas de CSS se pueden modificar en la memoria y luego guardar de nuevo en un archivo CSS? Gracias. – stepanian

+0

Sí. Analiza las reglas en una lista de Reglas, que se pueden modificar y luego volver a escribir en Cadena/Archivo usando toString(). Espero haber respondido a su pregunta. – corgrath

+0

Gracias. Lo estoy usando por cierto y está funcionando perfectamente para mí. – stepanian

13

Una biblioteca CSS para leer y escribir archivos de CSS2 y CSS3 en Java es ph-css de https://github.com/phax/ph-css Se basa en una gramática JavaCC y es compatible tanto con CSS2 como con CSS3 y, además, le permite analizar atributos de estilo HTML.

  • Es compatible con los cortes más comunes "*", "_" y "$" que no son compatibles con espec
  • Es compatible con CSS matemáticas - la calc() expresión
  • Es compatible con la regla @ página
  • Es compatible con los medios de CSS3 consultas
  • Es compatible con @viewport reglas
  • Es compatible con las reglas @keyframes
  • soporta reglas @supports - bastante nuevo
  • Es compatible con las normas @namespace
  • Usted puede obtener información de ubicación de origen para los diferentes elementos (+ número de línea en la columna para inicio y final - tanto para la etiqueta, así como para la construcción completa)

Desde 21 de mayo de 2013 a JDK 1.5 versión también está disponible, lo que lo hace más interesante para el desarrollo de Android

+1

Lo usé, y desde que se hizo la pregunta, evolucionó muy bien. La API agradable, un visitante que busca solo los elementos que necesita, simplemente carece de documentación (pero los documentos API son bastante agradables). Recomendado. – Martin

+0

Es un desperdicio que este lindo proyecto tenga poca documentación. Con un poco de trabajo, esto podría convertirse en un proyecto mucho más popular. – Gili

+0

Este me parece el mejor –

1

jStyleParser proporciona exactamente esta funcionalidad. Analiza todas las hojas de estilo referenciadas y las asigna a los nodos del árbol DOM.

1

Si usted lucha con CSSParser, ya que no parece haber ninguna documentación en absoluto, y que tal vez desea analizar sólo una cadena de CSS, como valor de parámetro de estilo, aquí es mi sencilla muestra de uso:

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()); 
} 
} 

La gran ventaja de CSSParser es que actualmente se encuentra en Maven. Entonces, si buscas algo bastante simple y directamente utilizable CSSParser parece ser una buena opción.

Notas: realiza la conversión automática para los colores del formato hexadecimal al formato rgb(), pero no proporciona ayuda con los tamaños con unidades, ¡los ve como una lista de valores! No tan bien.

1

Acabo de instalar mi propio CSS Stream Parser para Java, disponible en github. Lo que diferencia a este analizador incluye además:

  • Es un analizador de flujo, por lo que el manejador analizador recibirán notificación de todo el contenido nuevo inmediatamente después de cada artículo ha sido analizado
  • Soporte completo para todos los que actualmente documentados Al-Reglas
  • clases personalizados TokenSequence y Token procesos simplificar a los selectores de manipulación, etc.
  • Fácil de usar y entender
  • Útil para la validación o para aplicaciones más avanzadas
  • Escalable: diseñado para poder manejar cambios en las definiciones de CSS.
Cuestiones relacionadas