4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
XPathHelper.java
Go to the documentation of this file.
1 /*
2  * Project: Server for annotations sharing
3  * Subproject: Position of fragment of text in XML document
4  * Authors: Lukáš Martinák, Michael Angelov
5  * Edited by: Ing. Jaroslav Dytrych idytrych@fit.vutbr.cz
6  * File: XPathHelper.java
7  * Description: Helper class with util XPath methods
8  */
9 
10 /**
11  * @file XPathHelper.java
12  *
13  * @brief Helper class with util XPath methods
14  */
15 
16 package cz.vutbr.fit.knot.annotations.fragmentUpdater;
17 
18 import javax.xml.xpath.*;
19 import org.w3c.dom.Attr;
20 import org.w3c.dom.Document;
21 import org.w3c.dom.Node;
22 import org.w3c.dom.NodeList;
23 
24 /**
25  * Helper class with util XPath methods
26  *
27  * @brief Helper class with util XPath methods
28  * @author Lukáš Martinák, Michael Angelov
29  */
30 public class XPathHelper {
31 
32  public static final String DOCUMENT_XPATH = "/";
33 
34  /**
35  * Method for converting XPath string into XPath expression
36  *
37  * @param XPathString string representation of XPath
38  * @return XPath expression
39  */
40  public static XPathExpression XPathStringToExpression(String XPathString) throws XPathExpressionException {
41 
42  XPathFactory factory = XPathFactory.newInstance();
43  XPath xpath = factory.newXPath();
44  XPathExpression expr = (XPathExpression) xpath.compile(XPathString);
45 
46  return expr;
47  }
48 
49  /**
50  * Method for evaluating XPath expression
51  *
52  * @param document XML document in which XPath will be evaluated
53  * @param expr XPath expression which will be evaluated
54  * @return list of nodes matched by XPath expression
55  */
56  public static NodeList evaluateXPath(Document document, XPathExpression expr) throws XPathExpressionException {
57 
58  Object result;
59 
60  result = expr.evaluate(document, XPathConstants.NODESET);
61 
62  return (NodeList) result;
63  }
64 
65  /**
66  * Method for getting XPath index "[..]" of node amongst siblings
67  *
68  * @param node node to be examined
69  * @return index of node amongst siblings, beginning with 1
70  */
71  public static int XPathIndexOfNode(Node node) {
72  int offset = 1;
73 
74  if (node != null && node.getOwnerDocument() != null) {
75 
76  Node parentNode = node.getParentNode();
77  if (parentNode != null) {
78  Node prevSibling = node.getPreviousSibling();
79 
80  if (prevSibling != null
81  && prevSibling.getNodeType() == Node.DOCUMENT_TYPE_NODE
82  && node.getNodeType() == Node.ELEMENT_NODE
83  && node.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
84  // DOCTYPE and <html> elements have same name but
85  // in XPath <HTML> is really first node, not second.
86  // If previous sibling is DOCTYPE, node is element and both
87  // are on top level, there is no reason to check previous
88  // nodes.
89  return offset;
90  }
91 
92  short nodeType = node.getNodeType();
93  switch (nodeType) {
94 
95  case Node.ATTRIBUTE_NODE:
96  break;
97 
98  case Node.CDATA_SECTION_NODE: case Node.TEXT_NODE:
99  while (prevSibling != null) {
100  if (prevSibling.getNodeType() == Node.TEXT_NODE
101  || prevSibling.getNodeType() == Node.CDATA_SECTION_NODE) {
102  offset++;
103  }
104  prevSibling = prevSibling.getPreviousSibling();
105  }
106  break;
107 
108  case Node.COMMENT_NODE: case Node.PROCESSING_INSTRUCTION_NODE:
109  while (prevSibling != null) {
110  if (prevSibling.getNodeType() == nodeType) {
111  offset++;
112  }
113  prevSibling = prevSibling.getPreviousSibling();
114  }
115  break;
116 
117  case Node.ELEMENT_NODE:
118  while (prevSibling != null) {
119  if (prevSibling.getNodeName().equals(node.getNodeName())) {
120  offset++;
121  }
122  prevSibling = prevSibling.getPreviousSibling();
123  }
124  break;
125 
126  default:
127  while (prevSibling != null) {
128  offset++;
129  prevSibling = prevSibling.getPreviousSibling();
130  }
131  } // switch (nodeType) {
132  } // if (parentNode != null) {
133  } // if (node.getOwnerDocument() != null ...
134 
135  return offset;
136  } // XPathIndexOfNode()
137 
138  /**
139  * Method for getting XPath string representation of node in document
140  *
141  * @param node node whose XPath is being searched for
142  * @return string representation of XPath
143  */
144  public static String XPathStringOfNode(Node node) {
145 
146  if (node.getNodeType() == Node.DOCUMENT_NODE) {
147  return DOCUMENT_XPATH;
148  }
149 
150  String str = "";
151  Node currentNode = node;
152  int currentIndex = XPathIndexOfNode(currentNode);
153 
154  // generate termination node (cannot contain any child nodes) XPath string
155  switch (node.getNodeType()) {
156  case Node.TEXT_NODE:
157  case Node.CDATA_SECTION_NODE:
158  str = "/text()" + "[" + currentIndex + "]";
159  break;
160  case Node.COMMENT_NODE:
161  str = "/comment()" + "[" + currentIndex + "]";
162  break;
163  case Node.PROCESSING_INSTRUCTION_NODE:
164  str = "/processing-instruction()" + "[" + currentIndex + "]";
165  break;
166  case Node.ATTRIBUTE_NODE:
167  str = "/@" + ((Attr)node).getName();
168  break;
169  case Node.ELEMENT_NODE: // skip, to compute xpath will be used the name of element
170  break;
171  default:
172  str = "/node()" + "[" + currentIndex + "]";
173  }
174 
175  if (node.getNodeType() != Node.ELEMENT_NODE && currentNode != node.getOwnerDocument()) {
176  currentNode = node.getParentNode();
177  currentIndex = XPathIndexOfNode(currentNode);
178  }
179 
180  while (currentNode != null && currentNode != node.getOwnerDocument()) {
181  str = "/" + currentNode.getNodeName() + "[" + currentIndex + "]" + str;
182  currentNode = currentNode.getParentNode();
183  currentIndex = XPathIndexOfNode(currentNode);
184  }
185 
186  return str;
187  } // XPathStringOfNode()
188 
189  /**
190  * Gets the node determined in xpath from the document
191  *
192  * @param document Document
193  * @param path XPath of the node
194  * @return node
195  * @throws XPathExpressionException
196  */
197  public static Node getNode(Document document, String path) throws XPathExpressionException {
198  XPathFactory factory = XPathFactory.newInstance();
199  XPath xpath = factory.newXPath();
200  XPathExpression expr = xpath.compile(path);
201  NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
202 
203 
204  if (nodes.getLength() != 1) {
205  return null;
206  }
207 
208  return nodes.item(0);
209  }
210 
211 } // class XPathHelper
static NodeList evaluateXPath(Document document, XPathExpression expr)
static Node getNode(Document document, String path)
static XPathExpression XPathStringToExpression(String XPathString)