View Javadoc
1   package org.opentrafficsim.road.network.factory.xml;
2   
3   import java.util.ArrayList;
4   import java.util.Collections;
5   import java.util.Comparator;
6   import java.util.List;
7   
8   import org.w3c.dom.Element;
9   import org.w3c.dom.Node;
10  import org.w3c.dom.NodeList;
11  
12  import nl.tudelft.simulation.language.Throw;
13  
14  /**
15   * <p>
16   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
18   * <p>
19   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
20   * initial version Jul 23, 2015 <br>
21   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
22   */
23  public final class XMLParser
24  {
25      /** Utility class. */
26      private XMLParser()
27      {
28          // do not instantiate
29      }
30  
31      /**
32       * @param nodeList the list of nodes to process
33       * @param tag the tag to look for, e.g., LINK
34       * @return the nodes (which can contain nodeLists themselves) with the given tag
35       */
36      public static List<Node> getNodes(final NodeList nodeList, final String tag)
37      {
38          List<Node> result = new ArrayList<>();
39          for (int i = 0; i < nodeList.getLength(); i++)
40          {
41              Node node = nodeList.item(i);
42              if (node instanceof Element)
43              {
44                  if (tag.equals(node.getNodeName()))
45                  {
46                      result.add(node);
47                  }
48              }
49          }
50          return result;
51      }
52  
53      /**
54       * Returns nodes sorted by attributes and/or value. Nodes are sorted according to the given attribute order. In this order
55       * the node value can used by providing {@code null}.
56       * @param nodeList the list of nodes to process
57       * @param tag the tag to look for, e.g., LINK
58       * @param sortAttributes list of attributes, which may contain {@code null} to use the node value
59       * @return sorted nodes by attributes and/or value
60       */
61      public static List<Node> getNodesSorted(final NodeList nodeList, final String tag, final String... sortAttributes)
62      {
63          List<Node> result = getNodes(nodeList, tag);
64          Collections.sort(result, new Comparator<Node>()
65          {
66              /** {@inheritDoc} */
67              @Override
68              public int compare(final Node o1, final Node o2)
69              {
70                  for (String attribute : sortAttributes)
71                  {
72                      if (attribute == null)
73                      {
74                          Throw.when(o1.getNodeValue() == null || o2.getNodeValue() == null, RuntimeException.class,
75                                  "Tag %s cannot be sorted using it's value as tags without value are encountered.", tag);
76                          return o1.getNodeValue().compareTo(o2.getNodeValue());
77                      }
78                      Node n1 = o1.getAttributes().getNamedItem(attribute);
79                      Node n2 = o2.getAttributes().getNamedItem(attribute);
80                      int order = 0;
81                      if (n1 != null && n2 != null)
82                      {
83                          String attr1 = n1.getNodeValue();
84                          String attr2 = n2.getNodeValue();
85                          if (attr1 == null && attr2 != null)
86                          {
87                              order = -1;
88                          }
89                          else if (attr1 == null)
90                          {
91                              order = 0;
92                          }
93                          else if (attr2 == null)
94                          {
95                              order = 1;
96                          }
97                          else
98                          {
99                              order = attr1.compareTo(attr2);
100                         }
101                         if (order != 0)
102                         {
103                             return order;
104                         }
105                     }
106                 }
107                 return 0;
108             }
109         });
110         return result;
111     }
112 }