📄 xml.java
字号:
if (cursor.isText()) return cursor.getChars(); if (cursor.isFinish()) return ""; cursor.push(); boolean wanRawText = cursor.isStartdoc() && !cursor.toFirstChild(); cursor.pop(); return wanRawText ? cursor.getTextValue() : cursor.xmlText( opts ); } /** * * @return */ private XmlCursor newCursor () { XmlCursor curs; if (_anno != null) { curs = _anno.createCursor(); if (curs == null) { // Orphaned case. XmlObject doc = XmlObject.Factory.newInstance(); curs = doc.newCursor(); if (_anno._name != null) { curs.toNextToken(); curs.insertElement(_anno._name); curs.toPrevSibling(); } curs.setBookmark(_anno); } } else { XmlObject doc = XmlObject.Factory.newInstance(); curs = doc.newCursor(); } return curs; } /* * fUseStartDoc used by child(int index) the index is at startDoc is the element at the top-level * otherwise we always want to drill in. */ private boolean moveToChild(XmlCursor curs, long index, boolean fFirstChild, boolean fUseStartDoc) { if (index < 0) throw new IllegalArgumentException(); long idxChild = 0; if (!fUseStartDoc && curs.currentTokenType().isStartdoc()) { // We always move to the children of the top node. // todo: This assumes that we want have multiple top-level nodes. Which we should be able tohave. curs.toFirstContentToken(); } TokenType tt = curs.toFirstContentToken(); if (!tt.isNone() && !tt.isEnd()) { while (true) { if (index == idxChild) { return true; } tt = curs.currentTokenType(); if (tt.isText()) { curs.toNextToken(); } else if (tt.isStart()) { // Need to do this we want to be pointing at the text if that after the end token. curs.toEndToken(); curs.toNextToken(); } else if (tt.isComment() || tt.isProcinst()) { continue; } else { break; } idxChild++; } } else if (fFirstChild && index == 0) { // Drill into where first child would be.// curs.toFirstContentToken(); return true; } return false; } /** * * @return */ XmlCursor.TokenType tokenType() { XmlCursor.TokenType result; XmlCursor curs = newCursor(); if (curs.isStartdoc()) { curs.toFirstContentToken(); } result = curs.currentTokenType(); curs.dispose(); return result; } /** * * @param srcCurs * @param destCurs * @param fDontMoveIfSame * @return */ private boolean moveSrcToDest (XmlCursor srcCurs, XmlCursor destCurs, boolean fDontMoveIfSame) { boolean fMovedSomething = true; TokenType tt; do { if (fDontMoveIfSame && srcCurs.isInSameDocument(destCurs) && (srcCurs.comparePosition(destCurs) == 0)) { // If the source and destination are pointing at the same place then there's nothing to move. fMovedSomething = false; break; } // todo ***TLL*** Use replaceContents (when added) and eliminate children removes (see above todo). if (destCurs.currentTokenType().isStartdoc()) { destCurs.toNextToken(); } // todo ***TLL*** Can Eric support notion of copy instead of me copying then moving??? XmlCursor copyCurs = copy(srcCurs); copyCurs.moveXml(destCurs); copyCurs.dispose(); tt = srcCurs.currentTokenType(); } while (!tt.isStart() && !tt.isEnd() && !tt.isEnddoc()); return fMovedSomething; } /** * * @param cursToCopy * @return */ private XmlCursor copy (XmlCursor cursToCopy) { XmlObject xo = XmlObject.Factory.newInstance(); XmlCursor copyCurs = null; if (cursToCopy.currentTokenType().isText()) { try { // Try just as a textnode, to do that we need to wrap the text in a special fragment tag // that is not visible from the XmlCursor. copyCurs = XmlObject.Factory.parse("<x:fragment xmlns:x=\"http://www.openuri.org/fragment\">" + cursToCopy.getChars() + "</x:fragment>").newCursor(); if (!cursToCopy.toNextSibling()) { if (cursToCopy.currentTokenType().isText()) { cursToCopy.toNextToken(); // It's not an element it's text so skip it. } } } catch (Exception ex) { throw ScriptRuntime.typeError(ex.getMessage()); } } else { copyCurs = xo.newCursor(); copyCurs.toFirstContentToken(); if (cursToCopy.currentTokenType() == XmlCursor.TokenType.STARTDOC) { cursToCopy.toNextToken(); } cursToCopy.copyXml(copyCurs); if (!cursToCopy.toNextSibling()) // If element skip element. { if (cursToCopy.currentTokenType().isText()) { cursToCopy.toNextToken(); // It's not an element it's text so skip it. } } } copyCurs.toStartDoc(); copyCurs.toFirstContentToken(); return copyCurs; } private static final int APPEND_CHILD = 1; private static final int PREPEND_CHILD = 2; /** * * @param curs * @param xmlToInsert */ private void insertChild(XmlCursor curs, Object xmlToInsert) { if (xmlToInsert == null || xmlToInsert instanceof Undefined) { // Do nothing } else if (xmlToInsert instanceof XmlCursor) { moveSrcToDest((XmlCursor)xmlToInsert, curs, true); } else if (xmlToInsert instanceof XML) { XML xmlValue = (XML) xmlToInsert; // If it's an attribute, then change to text node if (xmlValue.tokenType() == XmlCursor.TokenType.ATTR) { insertChild(curs, xmlValue.toString()); } else { XmlCursor cursToInsert = ((XML) xmlToInsert).newCursor(); moveSrcToDest(cursToInsert, curs, true); cursToInsert.dispose(); } } else if (xmlToInsert instanceof XMLList) { XMLList list = (XMLList) xmlToInsert; for (int i = 0; i < list.length(); i++) { insertChild(curs, list.item(i)); } } else { // Convert to string and make XML out of it String xmlStr = ScriptRuntime.toString(xmlToInsert); XmlObject xo = XmlObject.Factory.newInstance(); // Create an empty document. XmlCursor sourceCurs = xo.newCursor(); sourceCurs.toNextToken(); // To hold the text. sourceCurs.insertChars(xmlStr); sourceCurs.toPrevToken(); // Call us again with the cursor. moveSrcToDest(sourceCurs, curs, true); } } /** * * @param childToMatch * @param xmlToInsert * @param addToType */ private void insertChild(XML childToMatch, Object xmlToInsert, int addToType) { XmlCursor curs = newCursor(); TokenType tt = curs.currentTokenType(); XmlCursor xmlChildCursor = childToMatch.newCursor(); if (tt.isStartdoc()) { tt = curs.toFirstContentToken(); } if (tt.isContainer()) { tt = curs.toNextToken(); while (!tt.isEnd()) { if (tt.isStart()) { // See if this child is the same as the one thep passed in if (curs.comparePosition(xmlChildCursor) == 0) { // Found it if (addToType == APPEND_CHILD) { // Move the cursor to just past the end of this element curs.toEndToken(); curs.toNextToken(); } insertChild(curs, xmlToInsert); break; } } // Skip over child elements if (tt.isStart()) { tt = curs.toEndToken(); } tt = curs.toNextToken(); } } xmlChildCursor.dispose(); curs.dispose(); } /** * * @param curs */ protected void removeToken (XmlCursor curs) { XmlObject xo = XmlObject.Factory.newInstance(); // Don't delete anything move to another document so it gets orphaned nicely. XmlCursor tmpCurs = xo.newCursor(); tmpCurs.toFirstContentToken(); curs.moveXml(tmpCurs); tmpCurs.dispose(); } /** * * @param index */ protected void removeChild(long index) { XmlCursor curs = newCursor(); if (moveToChild(curs, index, false, false)) { removeToken(curs); } curs.dispose(); } /** * * @param name * @return */ protected static javax.xml.namespace.QName computeQName (Object name) { if (name instanceof String) { String ns = null; String localName = null; String fullName = (String)name; localName = fullName; if (fullName.startsWith("\"")) { int idx = fullName.indexOf(":"); if (idx != -1) { ns = fullName.substring(1, idx - 1); // Don't include the "" around the namespace localName = fullName.substring(idx + 1); } } if (ns == null) { return new javax.xml.namespace.QName(localName); } else { return new javax.xml.namespace.QName(ns, localName); } } return null; } /** * * @param destCurs * @param newValue */ private void replace(XmlCursor destCurs, XML newValue) { if (destCurs.isStartdoc()) { // Can't overwrite a whole document (user really wants to overwrite the contents of). destCurs.toFirstContentToken(); } // Orphan the token -- don't delete it outright on the XmlCursor. removeToken(destCurs); XmlCursor srcCurs = newValue.newCursor(); if (srcCurs.currentTokenType().isStartdoc()) { // Cann't append a whole document (user really wants to append the contents of). srcCurs.toFirstContentToken(); } moveSrcToDest(srcCurs, destCurs, false); // Re-link a new annotation to this cursor -- we just deleted the previous annotation on entrance to replace. if (!destCurs.toPrevSibling()) { destCurs.toPrevToken(); } destCurs.setBookmark(new XScriptAnnotation(destCurs)); // todo would be nice if destCurs.toNextSibling went to where the next token if the cursor was pointing at the last token in the stream. destCurs.toEndToken(); destCurs.toNextToken(); srcCurs.dispose(); } /** * * @param currXMLNode * @param xmlValue * @return */ private boolean doPut(XMLName name, XML currXMLNode, XMLObjectImpl xmlValue) { boolean result = false; XmlCursor curs = currXMLNode.newCursor(); try { // Replace the node with this new xml value. XML xml; int toAssignLen = xmlValue.length(); for (int i = 0; i < toAssignLen; i++) { if (xmlValue instanceof XMLList) { xml = ((XMLList) xmlValue).item(i); } else { xml = (XML) xmlValue; } // If it's an attribute or text node, make text node. XmlCursor.TokenType tt = xml.tokenType(); if (tt == XmlCursor.TokenType.ATTR || tt == XmlCursor.TokenType.TEXT) { xml = makeXmlFromString(lib, name, xml.toString()); } if (i == 0) { // 1st assignment is replaceChild all others are appendChild replace(curs, xml); } else { insertChild(curs, xml); } } // We're done we've blown away the node because the rvalue was XML... result = true; } catch (Exception ex) { ex.printStackTrace();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -