Source code: diffxml/fmes/NodePos.java
1 /*
2 Class to return postion of a node
3
4 Copyright (C) 2002 Adrian Mouat
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 Author: Adrian Mouat
21 email: amouat@postmaster.co.uk
22 */
23
24 package diffxml.fmes;
25
26 import diffxml.*;
27 import org.w3c.dom.Node;
28 import org.w3c.dom.Document;
29 import org.w3c.dom.NodeList;
30 import org.apache.xerces.dom3.Node3;
31
32 public class NodePos
33 {
34
35 //Function to return charpos only
36 public static int getCharpos(Node n)
37 {
38
39 NodeList kids=n.getParentNode().getChildNodes();
40 int charpos=1;
41
42 Node3 n3=(Node3) n;
43 int i;
44 for (i=0;i<kids.getLength();i++)
45 {
46 if (n3.isSameNode(kids.item(i)))
47 break;
48 }
49
50 for (int y=(i-1); y>=0; y--)
51 {
52 if (kids.item(y).getNodeType()==Node.TEXT_NODE)
53 {
54 charpos=charpos+kids.item(y).getNodeValue().length();
55 db.p(kids.item(y).getNodeValue()+ " charpos "+charpos);
56 }
57 else
58 break;
59 }
60
61 return charpos;
62 }
63
64 //Returns XPath of given node in form needed for DUL, also gives charpos and length
65 //if needed
66 public static Pos get(Node n)
67 {
68 //db.on=true;
69 Pos n_pos=new Pos();
70 n_pos.path="null";
71 n_pos.charpos=-1;
72 n_pos.length=-1;
73 String xpath="";
74
75 //Keep boolean so we know if at top
76 boolean top=true;
77 //Have to init to something so x can be used in final comp
78 Node3 x=(Node3) n;
79
80 Node3 root = (Node3) n.getOwnerDocument().getDocumentElement();
81
82 if (n==null)
83 return n_pos;
84
85 do
86 {
87
88 db.p("Entered XPath");
89 db.p(n.getNodeName());
90 Node t=n.getParentNode();
91
92 int index=0;
93 NodeList kids = t.getChildNodes();
94 for(int i=0;i<kids.getLength();i++)
95 {
96 String tag=n.getNodeName();
97 x = (Node3) kids.item(i);
98 //Increment index, unless text node following text node
99
100 if (Table.tagnames)
101 {
102 if (tag.equals(x.getNodeName()))
103 index++;
104
105 //Exception to rule if text node
106 if (x.getNodeType()==Node.TEXT_NODE && i>0
107 && kids.item(i-1).getNodeType()==Node.TEXT_NODE)
108 index--;
109 }
110 else
111 {
112 index++;
113 if (x.getNodeType()==Node.TEXT_NODE && i>0
114 && kids.item(i-1).getNodeType()==Node.TEXT_NODE)
115 index--;
116 }
117
118 if (x.isSameNode(n))
119 {
120 xpath="[" + index + "]" + xpath;
121 if (Table.tagnames)
122 {
123 //special case for top node
124 if (top)
125 {
126 switch (x.getNodeType())
127 {
128 case Node.TEXT_NODE:
129 xpath="/text()"+xpath;
130 break;
131 case Node.COMMENT_NODE:
132 xpath="/comment()"+xpath;
133 break;
134 default:
135 xpath="/" + x.getNodeName()+xpath;
136 }
137 }
138 else
139 xpath="/" + x.getNodeName() + xpath;
140 }
141 else
142 xpath = "/node()" + xpath;
143
144 //Continue with next level
145 if (top)
146 {
147 top=false;
148
149 //Add charpos if prev or next node text
150 db.p("In top i=" + i + " x.nodevalue=" + x.getNodeValue());
151 db.p("Path=" + xpath);
152
153 if ((i>0 && kids.item(i-1).getNodeType()==Node.TEXT_NODE) || ( (i+1) < kids.getLength() && kids.item(i+1).getNodeType()==Node.TEXT_NODE))
154 {
155 //Loop backwards through nodes getting lengths if text
156 //Not sure if charpos will be 1 out..... (by XPath standard)
157 n_pos.charpos=1;
158 for (int y=(i-1); y>=0; y--)
159 {
160 if (kids.item(y).getNodeType()==Node.TEXT_NODE)
161 {
162 db.p("Extra Text value: " + kids.item(y).getNodeValue() + "END");
163 n_pos.charpos=n_pos.charpos+kids.item(y).getNodeValue().length();
164 db.p(kids.item(y).getNodeValue()+ " charpos "+n_pos.charpos);
165 }
166 else
167 break;
168 }
169 //Need length if current node text node
170 if (n.getNodeType()==Node.TEXT_NODE)
171 n_pos.length=n.getNodeValue().length();
172
173 }
174 }
175 break;
176 }
177 }
178 n=n.getParentNode();
179 }
180 while (!root.isSameNode(x));
181 n_pos.path=xpath;
182 db.on=false;
183 return n_pos;
184 }
185 }
186