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