Menu

How to get all the nodes with a property

2012-09-05
2012-09-11
  • Antonio Giovanni Schiavone

    It's quite easy, given a certain node, to get all his properties.

    But how i can get all the nodes with a certain property? ( for example, how i
    can get all the nodes in the document with the property margin-top?)

    A solution could be make a loop for all the nodes in the dom, testing if the
    node has that property. But is not so efficient.

    Is there' an easy and quick way to do that?

     
  • Radek Burget

    Radek Burget - 2012-09-05

    This is not a typical use-case. I am afraid, there is no optimal solution for
    this. However, you don't have to traverse the whole DOM tree - you may just go
    through the Map obtained from the evaluateDOM() method. This could be a
    bit faster and at least you will skip the nodes that do not have any style
    assigned.

     
  • Antonio Giovanni Schiavone

    It's a pity, a function similar to org.w3c.Document.getElementsByTagName()
    could be very useful!

    I didn't understand you small improvement.

    At the moment I get my map with:

    map = CSSFactory.assignDOM(DOM, Url, media, inherit);

    and when i want to access to a property (for example font-size) of the element
    "el" I use:

    NodeData nodeStyle = map.get(el);

    String PropertyValue = nodeStyle.getProperty("font-size").toString();

    Looping all of this code on every element in the DOM is not so quick! :(

     
  • Radek Burget

    Radek Burget - 2012-09-06

    Unfortuantely, the internal data structures of jStyleParser are not suitable
    for this. For efficiency, it would be necessary to create some index on
    property values, which is quite expensive. With traversing the map, I mean the
    following (very roughly):

    map = CSSFactory.assignDOM(DOM, Url, media, inherit); 
    for (Map.Entry<...> mapEntry : map.entrySet()) {
            Node node = mapEntry.getKey();
            NodeData nodeStyle = mapEntry.getValue();
            //test the style now
    }
    

    This way, you should test all the node styles more efficiently than with
    traversing the tree.

    Radek

     
  • Antonio Giovanni Schiavone

    IMHO, I'd love to have also this second "property-driven" map inside
    JStyleParser.

    I think quite all the people who works with css works also with html.

    With this second map html parsing and css parsing will be more similar.

    Generating this second map during the css parsing should be a small overhead.

    May I highlight it as "requested feature"? ;)

     
  • Antonio Giovanni Schiavone

    I wrote this simple class:

    public class PropertyDrivenMap {

    private StyleMap OriginalMap = null;

    private Document Dom = null;

    private Map<string, list\<node=""> > PropertyDriven = new HashMap<>();</string,>

    public PropertyDrivenMap(StyleMap OriginalMap, Document Dom)

    {

    this.OriginalMap = OriginalMap;

    this.Dom = Dom;

    }

    public void GenerateMap()

    {

    NodeList DomNodes = this.Dom.getElementsByTagName("*");

    for (int i = 0; i < DomNodes.getLength(); i++)

    {

    if (DomNodes.item(i).getNodeType() == Node.ELEMENT_NODE)

    {

    Element el = (Element) DomNodes.item(i);

    NodeData nodeStyle = OriginalMap.get(el);

    Iterator<string> iterator = nodeStyle.getPropertyNames().iterator();</string>

    while ( iterator.hasNext() )

    {

    String Property = iterator.next();

    List<node> NodeList = PropertyDriven.get(Property);</node>

    if (NodeList == null)

    {

    NodeList = new ArrayList<>();

    NodeList.add(el);

    PropertyDriven.put(Property, NodeList);

    }

    else

    {

    NodeList.add(el);

    }

    }

    }

    }

    }

    public List<node> getElementsByPropertyName(String Property)</node>

    {

    return this.PropertyDriven.get(Property);

    }

    }

    Applied to url http://www.libero.it, it traversed a
    Dom with about 7400 element, generating a "property-driven" map in few
    millisec on my notebook (Processor Intel i5-480M ).

     
  • Antonio Giovanni Schiavone

    There's no way to have something like this code built-in inside the library?

     
  • Radek Burget

    Radek Burget - 2012-09-11

    Hi, if you managed to solve the problem by this (relatively short) code, is it
    still necessary to add some support to the library? Actually, I am a bit
    afraid about the possible performance impact because building two maps takes
    more time than building one map. I mean your code is fine, although I would
    consider using the approach that I proposed above in your generateMap()
    method. The difference is that you don't have to traverse all the DOM nodes
    but only the elements affected by some style definitions.

    Radek

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.