1 32 33 package com.knowgate.dataxslt; 34 35 import java.io.IOException ; 36 import java.io.File ; 37 import java.io.FileReader ; 38 import java.io.UnsupportedEncodingException ; 39 40 import com.knowgate.debug.DebugFile; 41 import com.knowgate.misc.Gadgets; 42 import com.knowgate.dfs.FileSystem; 43 44 import org.w3c.dom.DOMException ; 45 46 55 public class XMLDocument { 56 57 private String sXMLDoc; 58 private String sFilePath; 59 private String sEncoding; 60 private FileSystem oFS; 61 62 public XMLDocument() { 63 oFS = new FileSystem(); 64 sEncoding = "UTF-8"; 65 } 66 67 69 76 public XMLDocument(String sFile) throws IOException , OutOfMemoryError { 77 oFS = new FileSystem(); 78 sEncoding = "UTF-8"; 79 load (sFile); 80 } 81 82 84 91 public XMLDocument(String sFile, String sEnc) throws IOException , OutOfMemoryError { 92 oFS = new FileSystem(); 93 sEncoding = sEnc; 94 load (sFile); 95 } 96 97 99 public String getCharacterEncoding() { 100 return sEncoding; 101 } 102 103 105 public void setCharacterEncoding(String sEnc) { 106 sEnc = sEncoding; 107 } 108 109 111 119 public void load (String sFile, String sEnc) throws IOException ,OutOfMemoryError { 120 121 if (DebugFile.trace) { 122 DebugFile.writeln("Begin XMLDocument.load(" + sFile + "," + sEnc + ")"); 123 DebugFile.incIdent(); 124 } 125 126 sEncoding = sEnc; 127 128 try { 129 sXMLDoc = oFS.readfilestr(sFile, sEncoding); 130 } catch (com.enterprisedt.net.ftp.FTPException neverthrown) { } 131 132 sFilePath = sFile; 133 134 if (DebugFile.trace) { 135 DebugFile.decIdent(); 136 DebugFile.writeln("End XMLDocument.load() : " + String.valueOf(sXMLDoc.length())); 137 } 138 } 140 142 150 public void load (String sFile) throws IOException ,OutOfMemoryError { 151 152 if (DebugFile.trace) { 153 DebugFile.writeln("Begin XMLDocument.load(" + sFile + ")"); 154 DebugFile.incIdent(); 155 } 156 157 try { 158 sXMLDoc = oFS.readfilestr(sFile, sEncoding); 159 } catch (com.enterprisedt.net.ftp.FTPException neverthrown) { } 160 161 sFilePath = sFile; 162 163 if (DebugFile.trace) { 164 DebugFile.decIdent(); 165 DebugFile.writeln("End XMLDocument.load() : " + String.valueOf(sXMLDoc.length())); 166 } 167 } 169 171 177 public void save(String sFile) throws IOException { 178 179 if (DebugFile.trace) { 180 DebugFile.writeln("Begin XMLDocument.save(" + sFile + ")"); 181 DebugFile.incIdent(); 182 } 183 184 oFS.writefilestr (sFile, sXMLDoc, sEncoding); 185 186 if (DebugFile.trace) { 187 188 if (sXMLDoc.length()>0) { 189 if (Character.isISOControl(sXMLDoc.charAt(0))) 190 DebugFile.writeln("Warning: document " + sFile + " starts with ISO control characters"); 191 if (Character.isISOControl(sXMLDoc.charAt(sXMLDoc.length()-1))) 192 DebugFile.writeln("Warning: document " + sFile + " ends with ISO control characters"); 193 } 194 195 DebugFile.decIdent(); 196 197 File oFileW = new File (sFile); 198 long lFileW = oFileW.length(); 199 200 DebugFile.writeln("End XMLDocument.save() : " + String.valueOf(lFileW)); 201 } 202 } 204 206 211 public void save() throws IOException { 212 save (sFilePath); 213 } 214 215 217 private static boolean isLastSibling (String sXMLDoc, int iFromIndex, 218 String sParent, String sSibling) { 219 220 int iEndParent = sXMLDoc.indexOf("</" + sParent, iFromIndex); 221 int iNextSibling = sXMLDoc.indexOf("<" + sSibling, iFromIndex); 222 223 if (iNextSibling==-1) 224 return true; 225 else 226 return iNextSibling>iEndParent; 227 } 229 231 private int seekNode(String sXPath) { 232 int iNodeCount; 233 int iNode; 234 int iAttr; 235 int iLeft; 236 int iRight; 237 String sCurrent; 238 String vNodes[]; String vAttrs[]; boolean bAttrs[]; 243 if (DebugFile.trace) { 244 DebugFile.writeln("Begin XMLDocument.seekNode(" + sXPath + ")"); 245 DebugFile.incIdent(); 246 } 247 248 vNodes = Gadgets.split(sXPath, "/"); 251 if (null==vNodes) { 252 iNodeCount = 0; 253 vAttrs = null; 254 bAttrs = null; 255 } 256 else { 257 iNodeCount = vNodes.length; 258 vAttrs = new String [iNodeCount]; 259 bAttrs = new boolean[iNodeCount]; 260 for (int a=0; a<iNodeCount; a++) bAttrs[a] = false; 261 } 262 263 for (int iTok=0; iTok<iNodeCount; iTok++) { 264 265 iLeft = vNodes[iTok].indexOf("["); 266 if (iLeft>0) { 267 iRight = vNodes[iTok].indexOf("]"); 268 269 if (iRight==-1) 270 throw new DOMException (DOMException.INVALID_ACCESS_ERR, "missing right bracket"); 271 272 vAttrs[iTok] = vNodes[iTok].substring(iLeft+1,iRight); 274 vAttrs[iTok] = vAttrs[iTok].replace('@',' '); 276 vAttrs[iTok] = vAttrs[iTok].replace((char)39,(char)34); 278 vAttrs[iTok] = vAttrs[iTok].trim(); 280 vNodes[iTok] = vNodes[iTok].substring(0, iLeft); 282 } 283 else 284 vAttrs[iTok] = ""; 285 286 if (DebugFile.trace) DebugFile.writeln("Token " + String.valueOf(iTok) + " : node=" + vNodes[iTok] + ", attr=" + vAttrs[iTok]); 287 } 289 iLeft = 0; 291 iNode = 0; 292 293 while (iNode<iNodeCount) { 294 296 iLeft = sXMLDoc.indexOf("<" + vNodes[iNode], iLeft); 297 if (iLeft<0) { 298 if (DebugFile.trace) DebugFile.writeln("Node " + vNodes[iNode] + " not found"); 299 throw new DOMException (DOMException.NOT_FOUND_ERR, "Node " + vNodes[iNode] + " not found"); 300 } 302 iRight = sXMLDoc.indexOf(">", iLeft+1); 303 if (iRight<0) { 304 if (DebugFile.trace) DebugFile.writeln("Unclosed Node " + vNodes[iNode] + " missing >"); 305 throw new DOMException (DOMException.SYNTAX_ERR, "Unclosed Node " + vNodes[iNode] + " missing >"); 306 } 307 308 sCurrent = sXMLDoc.substring(iLeft+1, iLeft+vNodes[iNode].length()+1); 309 310 if (vNodes[iNode].equals(sCurrent)) { 311 312 if (vAttrs[iNode].length()==0) { 313 iNode++; 315 } 316 317 else if (vAttrs[iNode].startsWith("position()")) { 319 320 String [] aAttrValue = Gadgets.split2(vAttrs[iNode], '='); 321 322 if (aAttrValue.length<2) 323 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, "position() function can only be declared equal to last() function"); 324 else { 325 if (aAttrValue[1].equals("last()")) { 326 if ( isLastSibling (sXMLDoc, iRight, vNodes[iNode-1], sCurrent) ) { 327 bAttrs[iNode] = true; 328 iNode++; 329 } } else 332 throw new DOMException (DOMException.NOT_SUPPORTED_ERR, "position() function can only be declared equal to last() function"); 333 } 334 } 335 else { 336 iAttr = sXMLDoc.indexOf(vAttrs[iNode], iLeft+1); 338 if (iAttr>iLeft && iAttr<iRight) { 339 bAttrs[iNode] = true; 340 iNode++; 341 } 342 } 343 } 345 if (iNode<iNodeCount) iLeft = iRight; 346 } 348 if (0==iLeft) { 349 for (int b=0; b<iNodeCount; b++) { 350 if (false == bAttrs[b]) { 351 if (DebugFile.trace) DebugFile.writeln("Attribute " + vAttrs[b] + " of node " + vNodes[b] + " not found"); 352 throw new DOMException (DOMException.NOT_FOUND_ERR, "Attribute " + vAttrs[b] + " of node " + vNodes[b] + " not found"); 353 } } } 357 if (DebugFile.trace) { 358 DebugFile.decIdent(); 359 DebugFile.writeln("End XMLDocument.seekNode() : " + String.valueOf(iLeft)); 360 } 361 362 return iLeft; 363 } 365 367 370 public String toString() { 371 return sXMLDoc; 372 } 373 374 376 391 public void addNode(String sAfterXPath, String sNode) throws DOMException { 392 String sCloseParent; 393 int iOpenParent; 394 int iCloseParent; 395 int iTailParent; 396 int iAngle; 397 int iSpace; 398 char b; 399 400 if (DebugFile.trace) { 401 DebugFile.writeln("Begin XMLDocument.addNode(" + sAfterXPath + "," + sNode + ")"); 402 DebugFile.incIdent(); 403 } 404 405 iOpenParent = seekNode(sAfterXPath); 406 407 if (DebugFile.trace) DebugFile.writeln("iOpenParent=" + String.valueOf(iOpenParent)); 408 409 iSpace = sXMLDoc.indexOf(" ", iOpenParent); 410 if (-1==iSpace) iSpace = 2147483647; 411 iAngle = sXMLDoc.indexOf(">", iOpenParent); 412 if (-1==iAngle) iSpace = 2147483647; 413 414 sCloseParent = "</" + sXMLDoc.substring(iOpenParent+1, iSpace<iAngle ? iSpace : iAngle) + ">"; 415 416 if (DebugFile.trace) DebugFile.writeln("sCloseParent=" + sCloseParent); 417 418 iCloseParent = sXMLDoc.indexOf(sCloseParent, iOpenParent); 419 420 if (DebugFile.trace) DebugFile.writeln("iCloseParent=" + String.valueOf(iCloseParent)); 421 422 if (iCloseParent<=0) 423 throw new DOMException (DOMException.NOT_FOUND_ERR, "Node " + sCloseParent + " not found"); 424 425 iSpace = 0; 426 iAngle = iCloseParent - 1; 427 b = sXMLDoc.charAt(iAngle); 428 while (b==' ' || b=='\t') { 429 iCloseParent--; 430 iSpace++; 431 b = sXMLDoc.charAt(--iAngle); 432 } 434 iCloseParent = iCloseParent+sCloseParent.length()+iSpace; 435 iTailParent = iCloseParent; 436 437 if (iTailParent<sXMLDoc.length()) 438 while (sXMLDoc.charAt(iTailParent)==(char)13 || sXMLDoc.charAt(iTailParent)==(char)10) iTailParent++; 439 440 StringBuffer oXMLDoc = new StringBuffer (iCloseParent+sNode.length()+(sXMLDoc.length()-iTailParent)+4); 441 442 oXMLDoc.append(sXMLDoc.substring(0, iCloseParent)); 443 oXMLDoc.append(sNode); 444 oXMLDoc.append('\n'); 445 446 if (iTailParent<sXMLDoc.length()) 447 oXMLDoc.append(sXMLDoc.substring(iTailParent)); 448 449 sXMLDoc = oXMLDoc.toString(); 450 oXMLDoc = null; 451 452 if (DebugFile.trace) { 453 DebugFile.decIdent(); 454 DebugFile.writeln("End XMLDocument.addNode()"); 455 } 456 } 458 460 468 public void addNodeAndSave(String sAfterXPath, String sNode) throws DOMException ,IOException { 469 String sCloseParent; 470 int iOpenParent; 471 int iCloseParent; 472 int iTailParent; 473 int iAngle; 474 int iSpace; 475 char b; 476 477 if (DebugFile.trace) { 478 DebugFile.writeln("Begin XMLDocument.addNodeAndSave(" + sAfterXPath + "," + sNode + ")"); 479 DebugFile.incIdent(); 480 } 481 482 iOpenParent = seekNode(sAfterXPath); 483 484 if (DebugFile.trace) DebugFile.writeln("iOpenParent=" + String.valueOf(iOpenParent)); 485 486 iSpace = sXMLDoc.indexOf(" ", iOpenParent); 487 if (-1==iSpace) iSpace = 2147483647; 488 iAngle = sXMLDoc.indexOf(">", iOpenParent); 489 if (-1==iAngle) iSpace = 2147483647; 490 491 sCloseParent = "</" + sXMLDoc.substring(iOpenParent+1,iSpace<iAngle ? iSpace : iAngle) + ">"; 492 493 if (DebugFile.trace) DebugFile.writeln("sCloseParent=" + sCloseParent); 494 495 iCloseParent = sXMLDoc.indexOf(sCloseParent, iOpenParent); 496 497 if (DebugFile.trace) DebugFile.writeln("iCloseParent=" + String.valueOf(iCloseParent)); 498 499 if (iCloseParent<=0) 500 throw new DOMException (DOMException.NOT_FOUND_ERR, "Node " + sCloseParent + " not found"); 501 502 iSpace = 0; 503 iAngle = iCloseParent - 1; 504 b = sXMLDoc.charAt(iAngle); 505 while (b==' ' || b=='\t') { 506 iCloseParent--; 507 iSpace++; 508 b = sXMLDoc.charAt(--iAngle); 509 } 511 iCloseParent = iCloseParent+sCloseParent.length()+iSpace; 512 iTailParent = iCloseParent; 513 514 if (iTailParent<sXMLDoc.length()) 515 while (sXMLDoc.charAt(iTailParent)==(char)13 || sXMLDoc.charAt(iTailParent)==(char)10) iTailParent++; 516 517 StringBuffer oXMLDoc = new StringBuffer (iCloseParent+sNode.length()+(sXMLDoc.length()-iTailParent)+4); 518 519 oXMLDoc.append(sXMLDoc.substring(0, iCloseParent)); 520 oXMLDoc.append(sNode); 521 oXMLDoc.append('\n'); 522 523 if (iTailParent<sXMLDoc.length()) 524 oXMLDoc.append(sXMLDoc.substring(iTailParent)); 525 526 sXMLDoc = oXMLDoc.toString(); 527 oXMLDoc = null; 528 529 if (DebugFile.trace) { 530 if (sXMLDoc.length()>0) { 531 if (Character.isISOControl(sXMLDoc.charAt(0))) 532 DebugFile.writeln("Warning: document " + sFilePath + " starts with ISO control characters"); 533 if (Character.isISOControl(sXMLDoc.charAt(sXMLDoc.length()-1))) 534 DebugFile.writeln("Warning: document " + sFilePath + " ends with ISO control characters"); 535 } 536 } 537 538 oFS.writefilestr(sFilePath, sXMLDoc, sEncoding); 539 540 if (DebugFile.trace) { 541 DebugFile.decIdent(); 542 543 File oFileW = new File (sFilePath); 544 long lFileW = oFileW.length(); 545 546 DebugFile.writeln("End XMLDocument.addNodeAndSave() : " + String.valueOf(lFileW)); 547 } 548 } 550 552 559 public void removeNode(String sXPath) throws DOMException { 560 int iStartParent; 561 int iEndParent; 562 int iBracket; 563 String sNodeName; 564 String vNodes[]; 565 566 if (DebugFile.trace) { 567 DebugFile.writeln("Begin XMLDocument.removeNode(" + sXPath + ")"); 568 DebugFile.incIdent(); 569 } 570 571 iStartParent = seekNode(sXPath); 572 573 vNodes = Gadgets.split(sXPath, "/"); 574 575 iBracket = vNodes[vNodes.length-1].indexOf("["); 576 577 if (iBracket>0) 578 sNodeName = vNodes[vNodes.length-1].substring(0, iBracket); 579 else 580 sNodeName = vNodes[vNodes.length-1]; 581 582 iEndParent = sXMLDoc.indexOf("</" + sNodeName + ">", iStartParent) + sNodeName.length()+3; 583 584 if (iEndParent==0) 585 throw new DOMException (DOMException.NOT_FOUND_ERR, "Node " + "</" + sNodeName + ">" + " not found"); 586 587 for (char b = sXMLDoc.charAt(iStartParent); 589 (b==' ') && iStartParent>0; 590 b = sXMLDoc.charAt(--iStartParent)) ; 591 592 for (char c = sXMLDoc.charAt(iEndParent); 594 (c=='\r' || c=='\n') && iEndParent<sXMLDoc.length(); 595 c = sXMLDoc.charAt(++iEndParent)) ; 596 597 sXMLDoc = sXMLDoc.substring(0, iStartParent) + sXMLDoc.substring(iEndParent); 598 599 if (DebugFile.trace) { 600 DebugFile.decIdent(); 601 DebugFile.writeln("End XMLDocument.removeNode()"); 602 } 603 } 605 607 614 public void removeNodeAndSave(String sXPath) throws DOMException ,IOException { 615 616 if (DebugFile.trace) { 617 DebugFile.writeln("Begin XMLDocument.removeNodeAndSave(" + sXPath + ")"); 618 DebugFile.incIdent(); 619 } 620 621 removeNode(sXPath); 622 623 oFS.writefilestr(sFilePath, sXMLDoc, sEncoding); 624 625 if (DebugFile.trace) { 626 DebugFile.decIdent(); 627 DebugFile.writeln("End XMLDocument.removeNodeAndSave()"); 628 } 629 } 631 } | Popular Tags |