问题
First I want to explain what am I doing and then my problem. I need to scan a css file and obtain all its internal links(images mainly), but I need to get the line number where the links were found.
Right now I am parsing the files using flute library and it works very well also I am using LineNumberReader in order to obtain the line number where a link was found, but this class throws an incorrect line number.
For example: the link ../../image/bg.gif is in the line number 350 but the method getLineNumber in the class LineNumberReader says 490.
So I will appreciate if some of you can drive me by the correct way and give me a possible explanation why the LineNumberReader class does it.
pd: another solution will be very appreciate.
- sorry the possibles typos, English is not my mother tongue.
回答1:
Another solution -- Have a look at these parser generating tools...
- Antlr - http://www.antlr.org/grammar/1240941192304/css21.g
- JavaCC - http://sourceforge.net/projects/cssparser/
The JavaCC and Antlr provide a way to get the line number and the column number.
The possible reason for the your problem... the line number one... could be because of the way parser generating tools work... They try to find out the best possible match... for that sometime they have to trackback/rewind the stream.... and due to this your LineNumberReader instance is going out of sync....
The ideal way to get line or column number is to use the methods provided by the tool itself..
回答2:
Hi @eakbas and @Favonius Thanks for your answer.
I finally got a solution, maybe it is not the best but at least works for me.
As I mentioned before I used the flute library to implement the DocumentHandler class of the package org.w3c.sac package in order to analyze the css file.
So I implemented the 'property' method, this method has 3 parameter, the property name, an LexicalUnit object and a boolean indicating that the property has the important statement or not.
public void property(String property, LexicalUnit lexicalUnit, boolean important)
As I need the line number where a specific property is found, I made a search and I could see that the class that flute uses to implement the LexicalUnit interface holds the line number(it is LexicalUnitImp), so I used reflexion to make a casting from LexicalUnit interface to one LexicalUnitImp object.
Class<?> clazz = ClassUtils.getClass("org.w3c.flute.parser.LexicalUnitImpl");
Object lexicalObject = clazz.cast(lexicalUnit);
Integer line = (Integer)MethodUtils.invokeMethod(lexicalObject, "getLineNumber", null, null);
I did it in that way because the class LexicalUnitImpl is 'protected' and I cannot cast it in a traditional way.
class LexicalUnitImpl implements LexicalUnit
Note: The class ClassUtils and MethodUtils are part of the commons-beanutils apache library.
回答3:
Alternatively you may use ph-css as a parsing library. Please see the example "Visit all URLs contained in a CSS" at https://github.com/phax/ph-css#code-examples for an example of how to extract URLs and determine the correct source position.
来源:https://stackoverflow.com/questions/3859763/parsing-a-css-file-with-java