| /* Copyright 2004 The Apache Software Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package xmlcursor.checkin; |
| |
| import org.apache.xmlbeans.*; |
| import org.apache.xmlbeans.XmlCursor.TokenType; |
| import org.apache.xmlbeans.XmlCursor.XmlBookmark; |
| import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; |
| import org.junit.Ignore; |
| import org.junit.Test; |
| import org.xml.sax.*; |
| import org.xml.sax.ext.LexicalHandler; |
| import xmlcursor.common.Common; |
| |
| import javax.xml.namespace.QName; |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| import java.io.StringReader; |
| import java.util.*; |
| |
| import static org.junit.Assert.*; |
| |
| public class StoreTests { |
| |
| static String[] _args; |
| static String _test; |
| |
| |
| private void streamTest(String xml) |
| throws Exception { |
| XmlObject x1 = XmlObject.Factory.parse(xml); |
| XmlObject x2 = XmlObject.Factory.parse(x1.newCursor().newXMLStreamReader()); |
| |
| String x1Text = x1.xmlText(); |
| String x2Text = x2.xmlText(); |
| |
| assertEquals(x1Text, x2Text); |
| } |
| |
| @Test |
| public void testXMLStreamReader() throws Exception { |
| streamTest("<a/>"); |
| streamTest("<a x='y'/>"); |
| streamTest("<a><b>foo</b></a>"); |
| streamTest("<a><b>fo<!--moo-->o<?goof ball?>dsfdf</b></a>"); |
| streamTest("<a xmlns='nnn'></a>"); |
| streamTest("<a x='y'><!---->x<b/><c p='q'>z</c></a>"); |
| streamTest("<a x='y'><!----><b>moo</b><c p='q'></c></a>"); |
| streamTest("<a>asa<b/>sdsd<c>aaz</c>adsasd</a>"); |
| streamTest("<a><?target value?></a>"); |
| streamTest("<n:a xmlns:n='nnn'></n:a>"); |
| streamTest("<j:a x='y' p='q' xmlns:j='k'></j:a>"); |
| streamTest("<foo xmlns=\"foo.com\"><bar>1</bar></foo>"); |
| streamTest("<foo><!--comment--><?target foo?></foo>"); |
| streamTest("<foo>a<bar>b</bar>c<bar>d</bar>e</foo>"); |
| streamTest("<foo xmlns:x=\"y\"><bar xmlns:x=\"z\"/></foo>"); |
| streamTest("<foo x=\"y\" p=\"r\"/>"); |
| } |
| |
| @Test |
| public void testReplaceContents() throws Exception { |
| XmlObject xDst = XmlObject.Factory.newInstance(); |
| XmlObject xSrc = XmlObject.Factory.parse("<foo/>"); |
| XmlObject newDst = xDst.set(xSrc); |
| assertEquals("<foo/>", newDst.xmlText()); |
| |
| xDst = XmlObject.Factory.parse("<bar/>"); |
| xSrc = XmlObject.Factory.parse("<foo/>"); |
| XmlCursor c = xDst.newCursor(); |
| c.toNextToken(); |
| xDst = c.getObject(); |
| xDst.set(xSrc); |
| c.toStartDoc(); |
| xDst = c.getObject(); |
| assertEquals("<bar><foo/></bar>", xDst.xmlText()); |
| |
| xDst = XmlObject.Factory.parse("<bar x='y'/>"); |
| xSrc = XmlObject.Factory.parse("<foo>moo</foo>"); |
| c = xDst.newCursor(); |
| c.toNextToken(); |
| c.toNextToken(); |
| xDst = c.getObject(); |
| xDst.set(xSrc); |
| c.toStartDoc(); |
| xDst = c.getObject(); |
| assertEquals("<bar x=\"moo\"/>", xDst.xmlText()); |
| } |
| |
| @Test(expected = Exception.class) |
| public void testSniffing() throws Exception { |
| XmlObject x; |
| |
| x = XmlObject.Factory.parse("<xoo/>"); |
| assertSame(x.schemaType(), XmlBeans.NO_TYPE); |
| |
| x = XmlObject.Factory.parse( |
| "<schema xmlns='http://www.w3.org/2001/XMLSchema'/>"); |
| assertSame(x.schemaType(), SchemaDocument.type); |
| |
| x = XmlObject.Factory.parse( |
| "<schema xmlns='http://www.w3.org/2001/XMLSchema/moo'/>"); |
| assertSame(x.schemaType(), XmlBeans.NO_TYPE); |
| |
| x = XmlObject.Factory.parse( |
| "<schema xmlns='http://www.w3.org/2001/XMLSchema'/>"); |
| assertSame(x.schemaType(), SchemaDocument.type); |
| |
| x = org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Factory.parse( |
| "<schema xmlns='http://www.w3.org/2001/XMLSchema'/>"); |
| assertSame(x.schemaType(), SchemaDocument.type); |
| |
| org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Factory.parse( |
| "<schema xmlns='http://www.w3.org/2001/XMLSchema/moo'/>"); |
| } |
| |
| @Test |
| public void testCursorStack() throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<foo x='y'/>"); |
| XmlCursor c = x.newCursor(); |
| c.push(); |
| c.toNextToken(); |
| c.push(); |
| c.toNextToken(); |
| assertTrue(c.isAttr()); |
| c.pop(); |
| assertTrue(c.isStart()); |
| c.pop(); |
| assertTrue(c.isStartdoc()); |
| } |
| |
| @Test |
| public void testImplicitNamespaces() throws Exception { |
| Map<String,String> namespaces = new HashMap<String,String>(); |
| namespaces.put("foo", "foo.com"); |
| namespaces.put("bar", "bar.com"); |
| namespaces.put("", "default.com"); |
| |
| XmlOptions options = new XmlOptions(); |
| options.put(XmlOptions.SAVE_IMPLICIT_NAMESPACES, namespaces); |
| |
| XmlObject x = XmlObject.Factory.newInstance(); |
| XmlCursor c = x.newCursor(); |
| |
| c.toNextToken(); |
| |
| c.beginElement("a", "foo.com"); |
| c.beginElement("b", "default.com"); |
| c.beginElement("c", "bar.com"); |
| |
| assertEquals("<foo:a><b><bar:c/></b></foo:a>", x.xmlText(options)); |
| } |
| |
| private static class Content implements ContentHandler, LexicalHandler { |
| public void startDocument() { |
| add("START_DOCUMENT"); |
| } |
| |
| public void endDocument() { |
| add("END_DOCUMENT"); |
| } |
| |
| public void startElement( |
| String namespaceURI, String localName, |
| String qName, Attributes atts) { |
| add("START_ELEMENT"); |
| add(" namespaceURI: " + namespaceURI); |
| add(" localName: " + localName); |
| // add( " qName: " + qName ); |
| |
| TreeSet sortedAttrs = new TreeSet(); |
| |
| for (int i = 0; i < atts.getLength(); i++) { |
| String ln = atts.getLocalName(i); |
| String uri = atts.getURI(i); |
| String qname = atts.getQName(i); |
| |
| if (ln.equals("xmlns")) |
| continue; |
| if (qname.startsWith("xmlns")) |
| continue; |
| |
| // if (ln.equals( "xmlns" )) |
| // ln = ""; |
| // |
| // if (uri.equals( "xmlns" )) |
| // uri = ""; |
| |
| sortedAttrs.add( |
| uri + "-" + ln + "-" + |
| atts.getQName(i) + "-" + atts.getType(i) + "-" + |
| atts.getValue(i)); |
| } |
| |
| for (Iterator i = sortedAttrs.iterator(); i.hasNext(); ) |
| add(" Attr: " + i.next()); |
| } |
| |
| public void endElement( |
| String namespaceURI, String localName, String qName) { |
| add("END_ELEMENT"); |
| add(" namespaceURI: " + namespaceURI); |
| add(" localName: " + localName); |
| // add( " qName: " + qName ); |
| } |
| |
| public void characters(char[] ch, int start, int length) { |
| if (length > 0) { |
| add("CHARACTERS"); |
| add(ch, start, length); |
| } |
| } |
| |
| public void comment(char[] ch, int start, int length) { |
| add("COMMENT"); |
| add(" Comment: ", ch, start, length); |
| } |
| |
| public void processingInstruction(String target, String data) { |
| add("PROCESSING_INSTRUCTION"); |
| add("target: " + target); |
| add("data: " + data); |
| } |
| |
| public void ignorableWhitespace(char[] ch, int start, int length) { |
| if (length > 0) { |
| add("IGNORABLE_WHITESPACE"); |
| add(" whitespace: ", ch, start, length); |
| } |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) { |
| add("START_PREFIX_MAPPING"); |
| // add( " prefix: " + prefix ); |
| add(" uri: " + uri); |
| } |
| |
| public void endPrefixMapping(String prefix) { |
| add("END_PREFIX_MAPPING"); |
| // add( " prefix: " + prefix ); |
| } |
| |
| public void startCDATA() { |
| add("START_CDATA"); |
| } |
| |
| public void endCDATA() { |
| add("END_CDATA"); |
| } |
| |
| public void startDTD(String name, String publicId, String systemId) { |
| add("START_DTD"); |
| add(" name: " + name); |
| add(" publicId: " + publicId); |
| add(" systemId: " + systemId); |
| } |
| |
| public void endDTD() { |
| add("END_DTD"); |
| } |
| |
| public void startEntity(String name) { |
| add("START_ENTITY"); |
| add(" name: " + name); |
| } |
| |
| public void endEntity(String name) { |
| add("END_ENTITY"); |
| add(" name: " + name); |
| } |
| |
| public void setDocumentLocator(Locator locator) { |
| // add( "START_DOCUMENT_LOCATOR" ); |
| } |
| |
| public void skippedEntity(String name) { |
| add("SKIPPED_ENTITY"); |
| add(" name: " + name); |
| } |
| |
| private void add(String s) { |
| _sb.append(s); |
| _sb.append("\n"); |
| } |
| |
| private void add(String s, char[] buf, int off, int cch) { |
| _sb.append(s); |
| if (buf != null) |
| _sb.append(buf, off, cch); |
| _sb.append("\n"); |
| } |
| |
| private void add(char[] buf, int off, int cch) { |
| _sb.append(buf, off, cch); |
| _sb.append("\n"); |
| } |
| |
| public boolean equals(Object that) { |
| return toString().equals(that.toString()); |
| } |
| |
| public String toString() { |
| return _sb.toString(); |
| } |
| |
| private StringBuilder _sb = new StringBuilder(); |
| } |
| |
| private void doTestSaxSaver(String xml) |
| throws Exception { |
| // ME |
| |
| Content content2 = new Content(); |
| |
| XmlObject x = XmlObject.Factory.parse(xml); |
| |
| x.save(content2, content2); |
| |
| // THEM |
| |
| SAXParserFactory spf = SAXParserFactory.newInstance(); |
| SAXParser sp = spf.newSAXParser(); |
| |
| XMLReader xr = sp.getXMLReader(); |
| |
| Content content1 = new Content(); |
| |
| xr.setProperty("http://xml.org/sax/properties/lexical-handler", content1); |
| xr.setFeature("http://xml.org/sax/features/namespace-prefixes", true); |
| xr.setFeature("http://xml.org/sax/features/namespaces", true); |
| xr.setFeature("http://xml.org/sax/features/validation", false); |
| |
| xr.setContentHandler(content1); |
| |
| InputSource is = new InputSource(new StringReader(xml)); |
| |
| xr.parse(is); |
| |
| assertEquals(content1, content2); |
| } |
| |
| @Test |
| public void testSaxSaver() |
| throws Exception { |
| doTestSaxSaver("<a xmlns='nnn'></a>"); |
| doTestSaxSaver("<a x='y'><!---->x<b/><c p='q'>z</c></a>"); |
| doTestSaxSaver("<a x='y'><!----><b>moo</b><c p='q'></c></a>"); |
| doTestSaxSaver("<a>asa<b/>sdsd<c>aaz</c>adsasd</a>"); |
| doTestSaxSaver("<a><?target value?></a>"); |
| doTestSaxSaver("<n:a xmlns:n='nnn'></n:a>"); |
| doTestSaxSaver("<j:a x='y' p='q' xmlns:j='k'></j:a>"); |
| } |
| |
| @Test |
| @Ignore |
| public void testParsing() throws Exception { |
| Random r = new Random(1); |
| |
| for (int i = 0; i < 100000; i++) { |
| String xml = makeRandomDocument(r); |
| XmlObject.Factory.parse(xml); |
| } |
| } |
| |
| private void doTestLineNumbers(String xml) |
| throws Exception { |
| int line = 1; |
| int col = 1; |
| |
| XmlCursor c = |
| XmlObject.Factory.parse( |
| xml, new XmlOptions().setLoadLineNumbers()). |
| newCursor(); |
| |
| for (int i = 0; i < xml.length(); i++) { |
| char ch = xml.charAt(i); |
| |
| if (ch == '<' && Character.isLetter(xml.charAt(i + 1))) { |
| while (!c.currentTokenType().isStart()) |
| c.toNextToken(); |
| |
| assertTrue(c.currentTokenType().isStart()); |
| |
| XmlLineNumber ln = |
| (XmlLineNumber) |
| c.getBookmark(XmlLineNumber.class); |
| |
| assertNotNull(ln); |
| |
| assertTrue(ln.getLine() == -1 || ln.getLine() == line); |
| assertTrue(ln.getColumn() == -1 || ln.getColumn() == col); |
| assertTrue(ln.getOffset() == -1 || ln.getOffset() == i); |
| |
| c.toNextToken(); |
| } |
| |
| if (ch == '\n') { |
| line++; |
| col = 1; |
| } else |
| col++; |
| } |
| } |
| |
| @Test |
| @Ignore |
| public void testLineNumbers() throws Exception { |
| Random r = new Random(1); |
| |
| for (int i = 0; i < 1000; i++) { |
| String xml = makeRandomDocument(r); |
| doTestLineNumbers(xml); |
| } |
| } |
| |
| private static class DocBuilder { |
| Random r; |
| StringBuilder sb; |
| |
| DocBuilder(Random _r, StringBuilder _sb) { |
| r = _r; |
| sb = _sb; |
| } |
| |
| void append(char ch) { |
| sb.append(ch); |
| } |
| |
| void append(String s) { |
| sb.append(s); |
| } |
| |
| public void whitespace() { |
| int p = r.nextInt(100); |
| |
| if (p < 20) |
| append('\t'); |
| else if (p < 40) |
| append('\n'); |
| else |
| append(' '); |
| } |
| |
| void whitespaces() { |
| for (int i = r.nextInt(8); i > 0; i--) |
| whitespace(); |
| } |
| |
| char makeLetter() { |
| return (char) (((int) 'a') + r.nextInt(26)); |
| } |
| |
| public void letter() { |
| append(makeLetter()); |
| } |
| |
| void charEntity() { |
| switch (r.nextInt(5)) { |
| case 0: |
| append("<"); |
| break; |
| case 1: |
| append(">"); |
| break; |
| case 2: |
| append("&"); |
| break; |
| case 3: |
| append("'"); |
| break; |
| case 4: |
| append("""); |
| break; |
| } |
| } |
| |
| public void text() { |
| for (int i = r.nextInt(20); i > 0; i--) { |
| int p = r.nextInt(100); |
| |
| if (p < 70) |
| letter(); |
| else if (p < 74) |
| charEntity(); |
| else |
| whitespace(); |
| } |
| } |
| |
| String makeNcName() { |
| StringBuilder name = new StringBuilder(); |
| |
| for (; ; ) { |
| char ch = makeLetter(); |
| |
| if (ch == 'x' || ch == 'X') |
| continue; |
| |
| name.append(ch); |
| |
| break; |
| } |
| |
| for (int i = r.nextInt(20); i > 0; i--) |
| name.append(makeLetter()); |
| |
| return name.toString(); |
| } |
| |
| void ncName() { |
| append(makeNcName()); |
| } |
| |
| public void comment() { |
| append("<!--"); |
| text(); |
| append("-->"); |
| } |
| |
| public void procinst() { |
| append("<?"); |
| ncName(); |
| |
| if (r.nextInt(100) < 90) { |
| whitespace(); |
| text(); |
| } |
| |
| append("?>"); |
| } |
| |
| void whiteContent() { |
| for (; ; ) { |
| int p = r.nextInt(100); |
| |
| if (p < 20) |
| break; |
| else if (p < 50) |
| whitespaces(); |
| else if (p < 70) |
| comment(); |
| else |
| procinst(); |
| } |
| } |
| |
| void xmlDecl() { |
| append("<?xml version=\"1.0\"?>"); |
| } |
| |
| public void content(int depth) { |
| for (int i = r.nextInt(10); i > 0; i--) { |
| switch (r.nextInt(4)) { |
| case 0: |
| elementContent(depth + 1); |
| break; |
| |
| case 1: |
| text(); |
| break; |
| case 2: |
| comment(); |
| break; |
| case 3: |
| procinst(); |
| break; |
| } |
| } |
| } |
| |
| public void attribute() { |
| ncName(); |
| |
| if (r.nextInt(100) == 0) |
| whitespaces(); |
| |
| append('='); |
| |
| if (r.nextInt(100) == 0) |
| whitespaces(); |
| |
| char q = r.nextInt(2) == 0 ? '\'' : '"'; |
| |
| append(q); |
| |
| text(); |
| |
| append(q); |
| } |
| |
| void elementContent(int depth) { |
| // If depth == 0, guarantee an element, otherwise, as depth |
| // increases, the probablility we'll spit out an element |
| // gets smaller. |
| |
| if (r.nextInt(depth + 1) <= 1) { |
| String name = makeNcName(); |
| |
| append('<'); |
| append(name); |
| |
| if (r.nextInt(100) == 0) |
| whitespaces(); |
| |
| HashMap attrs = new HashMap(); |
| |
| for (int i = r.nextInt(3); i > 0; i--) { |
| append(' '); |
| |
| String aname; |
| |
| for (; ; ) { |
| aname = makeNcName(); |
| |
| if (!attrs.containsKey(aname)) |
| break; |
| } |
| |
| attrs.put(aname, null); |
| |
| append(aname); |
| |
| if (r.nextInt(100) == 0) |
| whitespaces(); |
| |
| append('='); |
| |
| if (r.nextInt(100) == 0) |
| whitespaces(); |
| |
| char q = r.nextInt(2) == 0 ? '\'' : '"'; |
| |
| append(q); |
| |
| text(); |
| |
| append(q); |
| |
| if (r.nextInt(10) == 0) |
| whitespaces(); |
| } |
| |
| append('>'); |
| |
| content(depth); |
| |
| append("</"); |
| append(name); |
| |
| if (r.nextInt(100) == 0) |
| whitespaces(); |
| |
| append('>'); |
| } |
| } |
| |
| public void document() { |
| if (r.nextInt(2) == 0) |
| xmlDecl(); |
| |
| whiteContent(); |
| |
| elementContent(0); |
| |
| whiteContent(); |
| } |
| } |
| |
| private String makeRandomDocument(Random r) { |
| StringBuilder sb = new StringBuilder(); |
| |
| DocBuilder db = new DocBuilder(r, sb); |
| |
| db.document(); |
| |
| return sb.toString(); |
| } |
| |
| private static class MyMark extends XmlBookmark { |
| } |
| |
| @Test |
| public void testBookmarks() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<foo x='y'>abcdefg<!---->xy</foo>"); |
| |
| XmlCursor c = x.newCursor(); |
| MyMark m1 = new MyMark(); |
| c.setBookmark(m1); |
| |
| c.toNextToken(); |
| MyMark m2 = new MyMark(); |
| c.setBookmark(m2); |
| |
| c.toNextToken(); |
| MyMark m3 = new MyMark(); |
| c.setBookmark(m3); |
| |
| c.toNextToken(); |
| MyMark m4 = new MyMark(); |
| c.setBookmark(m4); |
| |
| c.toNextChar(1); |
| MyMark m5 = new MyMark(); |
| c.setBookmark(m5); |
| |
| c.toNextChar(3); |
| MyMark m6 = new MyMark(); |
| c.setBookmark(m6); |
| |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextToken(); |
| MyMark m7 = new MyMark(); |
| c.setBookmark(m7); |
| |
| c.toNextToken(); |
| MyMark m8 = new MyMark(); |
| c.setBookmark(m8); |
| |
| c.toStartDoc(); |
| |
| assertSame(c.getBookmark(MyMark.class), m1); |
| assertSame(c.toNextBookmark(MyMark.class), m2); |
| assertSame(c.toNextBookmark(MyMark.class), m3); |
| assertSame(c.toNextBookmark(MyMark.class), m4); |
| assertSame(c.toNextBookmark(MyMark.class), m5); |
| assertSame(c.toNextBookmark(MyMark.class), m6); |
| assertSame(c.toNextBookmark(MyMark.class), m7); |
| assertSame(c.toNextBookmark(MyMark.class), m8); |
| assertNull(c.toNextBookmark(MyMark.class)); |
| |
| c.toEndDoc(); |
| |
| assertSame(c.getBookmark(MyMark.class), m8); |
| assertSame(c.toPrevBookmark(MyMark.class), m7); |
| assertSame(c.toPrevBookmark(MyMark.class), m6); |
| assertSame(c.toPrevBookmark(MyMark.class), m5); |
| assertSame(c.toPrevBookmark(MyMark.class), m4); |
| assertSame(c.toPrevBookmark(MyMark.class), m3); |
| assertSame(c.toPrevBookmark(MyMark.class), m2); |
| assertSame(c.toPrevBookmark(MyMark.class), m1); |
| assertNull(c.toPrevBookmark(MyMark.class)); |
| } |
| |
| @Test |
| public void testSetName() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<foo x='a'/>"); |
| XmlCursor c = x.newCursor(); |
| c.toNextToken(); |
| c.setName(new QName("bar")); |
| c.toNextToken(); |
| c.setName(new QName("y")); |
| |
| assertEquals("<bar y=\"a\"/>", x.xmlText()); |
| } |
| |
| // |
| // Basic load up a file and iterate through it |
| // |
| @Test |
| public void testBasicXml() |
| throws Exception { |
| XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor(); |
| |
| int n = 0; |
| |
| for (; ; ) { |
| TokenType t = c.toNextToken(); |
| |
| n++; |
| |
| if (t == TokenType.NONE) |
| break; |
| } |
| |
| assertEquals(6, n); |
| } |
| |
| // |
| // Make sure the tokens going forward the the reverse of the tokens |
| // going backward |
| // |
| @Test |
| public void testConsistentTokenOrder() |
| throws Exception { |
| ArrayList<TokenType> l = new ArrayList<TokenType>(); |
| |
| XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor(); |
| |
| |
| for (; ; ) { |
| // System.err.println(c.currentTokenType()); |
| l.add(c.currentTokenType()); |
| |
| if (c.toNextToken() == TokenType.NONE) |
| break; |
| } |
| |
| c.toEndDoc(); |
| // System.err.println("Reversing"); |
| |
| for (int i = l.size() - 1; ; i--) { |
| // System.err.println(c.currentTokenType()); |
| assertEquals(l.get(i), c.currentTokenType()); |
| |
| if (c.toPrevToken() == TokenType.NONE) |
| break; |
| } |
| } |
| |
| // Make sure you can't insert text before the doc begin |
| // going backward |
| @Test(expected = IllegalStateException.class) |
| public void testIllegalTextInsert() |
| throws Exception { |
| XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor(); |
| c.insertChars("Ho ho ho"); |
| } |
| |
| // Make sure getText works in a basic way |
| @Test |
| public void testgetText() |
| throws Exception { |
| XmlCursor c = XmlObject.Factory.parse(Common.XML_ATTR_TEXT, null).newCursor(); |
| assertEquals("ab", c.getTextValue()); // Doc node |
| |
| c.toNextToken(); |
| assertEquals("ab", c.getTextValue()); // Doc elem |
| |
| c.toNextToken(); |
| assertEquals("y", c.getTextValue()); // Attr x |
| |
| c.toNextToken(); |
| assertEquals("ab", c.getChars()); // Text |
| |
| c.toNextChar(1); |
| assertEquals("b", c.getChars()); // Text |
| |
| c.toNextToken(); |
| assertEquals(0, c.getChars().length()); // End tag |
| |
| c.toNextToken(); |
| assertEquals(0, c.getChars().length()); // End doc |
| } |
| |
| // |
| // Text XMLInputStream support |
| // |
| |
| private void doSaverTest(String xml) throws Exception { |
| XmlCursor c = XmlObject.Factory.parse(xml).newCursor(); |
| assertEquals(xml, c.xmlText()); |
| } |
| |
| private void doSaveTest(String xml) throws Exception { |
| doSaverTest(xml); |
| } |
| |
| @Test |
| public void testCDATA() throws Exception { |
| // https://issues.apache.org/jira/browse/XMLBEANS-404 |
| String xml = "<foo>Unable to render embedded object: <![CDATA[>>>>>>>><<<<<<<<<<<]]></foo>"; |
| String expected = "<foo><![CDATA[Unable to render embedded object: >>>>>>>><<<<<<<<<<<]]></foo>"; |
| XmlOptions options = new XmlOptions().setSaveCDataLengthThreshold(0); |
| XmlCursor c = XmlObject.Factory.parse(xml, options).newCursor(); |
| assertEquals(expected, c.xmlText(options)); |
| } |
| |
| @Test |
| public void testSaving() throws Exception { |
| doSaveTest("<foo xmlns=\"foo.com\"><bar>1</bar></foo>"); |
| doSaveTest("<foo><!--comment--><?target foo?></foo>"); |
| doSaveTest("<foo>a<bar>b</bar>c<bar>d</bar>e</foo>"); |
| doSaveTest("<foo xmlns:x=\"y\"><bar xmlns:x=\"z\"/></foo>"); |
| doSaveTest("<foo x=\"y\" p=\"r\"/>"); |
| |
| String s = "<foo>aaa</foo>bbb"; |
| s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s; |
| s = "<bar>xxxx" + s + "</bar>"; |
| |
| doSaveTest(s); |
| |
| XmlObject x = |
| XmlObject.Factory.parse("<foo xmlns:a='a.com'><bar xmlns:a='b.com'/></foo>"); |
| |
| XmlCursor c = x.newCursor(); |
| |
| c.toFirstChild(); |
| c.toFirstChild(); |
| |
| assertEquals("<bar xmlns:a=\"b.com\"/>", c.xmlText()); |
| |
| x = XmlObject.Factory.parse("<foo xmlns:a='a.com'><bar/></foo>"); |
| |
| c = x.newCursor(); |
| |
| c.toFirstChild(); |
| c.toFirstChild(); |
| |
| assertEquals("<bar xmlns:a=\"a.com\"/>", c.xmlText()); |
| } |
| |
| |
| private XmlCursor navDoc(XmlObject x, String dirs) { |
| return navCursor(x.newCursor(), dirs); |
| } |
| |
| private XmlCursor navNewCursor(XmlCursor c, String dirs) { |
| return navCursor(c.newCursor(), dirs); |
| } |
| |
| // |
| // Format: |
| // |
| // ( [-][N] type ) * |
| // |
| // type: |
| // |
| // c - character |
| // t - token |
| // p - parent element |
| // s - sibling element |
| // d - descendent (child) element |
| // r - end of the doc (root) |
| // b - begin of the doc |
| // |
| |
| private XmlCursor navCursor(XmlCursor c, String dirs) { |
| int n = 0; |
| boolean prev = false; |
| |
| for (int i = 0; i < dirs.length(); i++) { |
| char ch = dirs.charAt(i); |
| |
| if (ch == '-') { |
| prev = !prev; |
| continue; |
| } else if (ch >= '0' && ch <= '9') { |
| n = n * 10 + (ch - '0'); |
| continue; |
| } |
| |
| if (n == 0) |
| n = 1; |
| |
| if (ch == 'c') { |
| if (prev) |
| assertEquals(c.toPrevChar(n), n); |
| else |
| assertEquals(c.toNextChar(n), n); |
| } else if (ch == 't') { |
| while (n-- > 0) { |
| if (prev) |
| assertNotSame(c.toPrevToken(), TokenType.NONE); |
| else |
| assertNotSame(c.toNextToken(), TokenType.NONE); |
| } |
| } else if (ch == 'p') { |
| assertTrue(!prev); |
| |
| while (n-- > 0) |
| assertTrue(c.toParent()); |
| } else if (ch == 'r') { |
| assertTrue(!prev); |
| assertEquals(1, n); |
| |
| c.toEndDoc(); |
| } else if (ch == 'b') { |
| assertTrue(!prev); |
| assertEquals(1, n); |
| |
| c.toStartDoc(); |
| } else if (ch == 's') { |
| while (n-- > 0) { |
| if (prev) |
| assertTrue(c.toPrevSibling()); |
| else |
| assertTrue(c.toNextSibling()); |
| } |
| } else if (ch == 'd') { |
| assertTrue(!prev); |
| |
| while (n-- > 0) |
| assertTrue(c.toFirstChild()); |
| } else { |
| fail(); |
| } |
| |
| n = 0; |
| prev = false; |
| } |
| |
| return c; |
| } |
| |
| @Test |
| public void testOps() |
| throws Exception { |
| XmlObject x, x2, y; |
| XmlCursor cFrom, cTo, cTemp, cTemp2, c, d; |
| XmlBookmark anno; |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>abcdef</foo>"); |
| cFrom = navDoc(x, "d"); |
| cTo = navNewCursor(cFrom, ""); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| XmlOptions options = new XmlOptions(); |
| |
| options.put( |
| XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT, |
| new QName(null, "bar")); |
| |
| assertTrue( |
| x.xmlText(options).equals("<bar>[TO]<foo>abcdef</foo>[FROM]</bar>") || |
| x.xmlText(options).equals("<bar>[FROM]<foo>abcdef</foo>[TO]</bar>")); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>abcdef</foo>"); |
| |
| cFrom = navDoc(x, "d"); |
| cTo = navNewCursor(cFrom, "ttt"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertTrue( |
| x.xmlText(options).equals("<bar><foo>abcdef</foo>[FROM][TO]</bar>") || |
| x.xmlText(options).equals("<bar><foo>abcdef</foo>[TO][FROM]</bar>")); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>abcdef</foo>"); |
| |
| cFrom = navDoc(x, "d"); |
| cTo = navNewCursor(cFrom, "t3c"); |
| assertTrue(!cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<bar>[FROM]<foo>abc[TO]def</foo></bar>", x.xmlText(options)); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b></r>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navNewCursor(cFrom, "r-1t"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<r>[FROM]<b>pqr</b><a>xyz</a>[TO]</r>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navNewCursor(cFrom, "r-1t-1c"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<r>[FROM]<b>pqr</b>A<a>xyz</a>[TO]B</r>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navNewCursor(cFrom, "stc"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<r>[FROM]<b>p<a>xyz</a>[TO]qr</b>AB</r>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navDoc(x, "d"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| testTextFrag(x.xmlText(), "<a>xyz</a>[TO]<r>[FROM]<b>pqr</b>AB</r>"); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a><b>pqr</b>AB</r>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navDoc(x, "r"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<bar><r>[FROM]<b>pqr</b>AB</r><a>xyz</a>[TO]</bar>", x.xmlText(options)); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a></r>"); |
| x2 = XmlObject.Factory.parse("<s></s>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navDoc(x2, "dt"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<r>[FROM]</r>", x.xmlText()); |
| assertEquals("<s><a>xyz</a>[TO]</s>", x2.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>pq</a><b></b></r>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navDoc(x, "ddst"); |
| cTemp = navDoc(x, "ddt1c"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| cTemp.insertChars("[TEMP]"); |
| |
| assertEquals("<r>[FROM][TEMP]<b><a>pq</a>[TO]</b></r>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>abcdef</foo>"); |
| |
| cFrom = navDoc(x, "2t2c"); |
| cTo = navNewCursor(cFrom, "-1c"); |
| cFrom.moveChars(2, cTo); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<foo>acd[TO]b[FROM]ef</foo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>abcdef</foo>"); |
| |
| cFrom = navDoc(x, "2t2c"); |
| cTo = navNewCursor(cFrom, "3c"); |
| cFrom.moveChars(2, cTo); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<foo>ab[FROM]ecd[TO]f</foo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<bar><foo>abcdef</foo><foo>123456</foo></bar>"); |
| |
| cFrom = navDoc(x, "3t2c"); |
| cTo = navNewCursor(cFrom, "3t3c"); |
| cFrom.moveChars(2, cTo); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<bar><foo>ab[FROM]ef</foo><foo>123cd[TO]456</foo></bar>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<bar><foo>abcdef</foo><foo>123456</foo></bar>"); |
| |
| cFrom = navDoc(x, "2d"); |
| cTo = navDoc(x, "2dst2c"); |
| assertTrue(cFrom.copyXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals(x.xmlText(), |
| "<bar>[FROM]<foo>abcdef</foo><foo>12" + |
| "<foo>abcdef</foo>[TO]3456</foo></bar>"); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<r><a>xyz</a></r>"); |
| x2 = XmlObject.Factory.parse("<s></s>"); |
| |
| cFrom = navDoc(x, "dd"); |
| cTo = navDoc(x2, "dt"); |
| assertTrue(cFrom.copyXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<r>[FROM]<a>xyz</a></r>", x.xmlText()); |
| assertEquals("<s><a>xyz</a>[TO]</s>", x2.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse( |
| "<bar><foo>abcdef</foo>blah<foo>123456</foo></bar>"); |
| |
| cFrom = navDoc(x, "2d"); |
| cTo = navDoc(x, "2dst2c"); |
| assertTrue(cFrom.copyXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals(x.xmlText(), "<bar>[FROM]<foo>abcdef</foo>blah<foo>12" + |
| "<foo>abcdef</foo>[TO]3456</foo></bar>"); |
| |
| // |
| |
| x = XmlObject.Factory.parse( |
| "<bar><foo x='y'>abcdef</foo><foo>123456</foo>7890</bar>"); |
| |
| cFrom = navDoc(x, "2dt"); |
| cTo = navDoc(x, "2dst"); |
| cTemp = navDoc(x, "2dst3c"); |
| cTemp2 = navDoc(x, "2ds3t2c"); |
| assertTrue(cFrom.copyXml(cTo)); |
| cTemp.insertChars("[TEMP]"); |
| cTemp2.insertChars("[TEMP2]"); |
| |
| assertEquals(x.xmlText(), |
| "<bar><foo x=\"y\">abcdef</foo>" + |
| "<foo x=\"y\">123[TEMP]456</foo>78[TEMP2]90</bar>"); |
| |
| // |
| |
| x = XmlObject.Factory.parse( |
| "<bar>xy<foo x='y'>abcdef</foo>pqr<foo>123456</foo></bar>"); |
| |
| cFrom = navDoc(x, "2d"); |
| cTo = navDoc(x, "2ds-2c"); |
| |
| assertTrue(cFrom.removeXml()); |
| |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<bar>xy[FROM]p[TO]qr<foo>123456</foo></bar>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse( |
| "<bar>xy<foo x='y'>abcdef</foo>pqr<foo>123456</foo></bar>"); |
| |
| cFrom = navDoc(x, "2d2t2c"); |
| cTo = navDoc(x, "2d2t5c"); |
| |
| cFrom.removeChars(2); |
| |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals(x.xmlText(), |
| "<bar>xy<foo x=\"y\">ab[FROM]e[TO]f" + |
| "</foo>pqr<foo>123456</foo></bar>"); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<bar><!---->abc</bar>"); |
| |
| cFrom = navDoc(x, "tt"); |
| cTo = navDoc(x, "tttc"); |
| |
| assertTrue(cFrom.removeXml()); |
| |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| |
| assertEquals("<bar>[FROM]a[TO]bc</bar>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.newInstance(); |
| |
| cTo = navDoc(x, "t"); |
| cTo.insertElement("boo"); |
| cTo.toPrevToken(); |
| cTo.insertElement("moo"); |
| cTo.toPrevToken(); |
| cTo.insertElement("goo"); |
| |
| assertEquals("<boo><moo><goo/></moo></boo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.newInstance(); |
| |
| cTo = navDoc(x, "t"); |
| cTo.insertElement("boo"); |
| cTo.toPrevToken(); |
| cTo.insertElement("moo"); |
| cTo.toPrevToken(); |
| cTo.insertAttributeWithValue("x", "y"); |
| |
| assertEquals("<boo><moo x=\"y\"/></boo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<bar x='y'>abc</bar>"); |
| cTo = navDoc(x, "tt"); |
| cTo.insertAttributeWithValue("p", "q"); |
| |
| assertEquals("<bar p=\"q\" x=\"y\">abc</bar>", x.xmlText()); |
| |
| // Text XmlBookmark |
| |
| x = XmlObject.Factory.parse("<r><foo>abc</foo><bar></bar></r>"); |
| cFrom = navDoc(x, "tt"); |
| anno = new Anno(); |
| cFrom.setBookmark(anno); |
| cTo = navDoc(x, "6t"); |
| assertTrue(cFrom.moveXml(cTo)); |
| cFrom.insertChars("[FROM]"); |
| cTo.insertChars("[TO]"); |
| anno.createCursor().insertChars("[ANNO]"); |
| |
| assertEquals("<r>[FROM]<bar>[ANNO]<foo>abc</foo>[TO]</bar></r>", x.xmlText()); |
| |
| // Test content ops |
| |
| x = XmlObject.Factory.parse("<foo x='y'>abc</foo>"); |
| y = XmlObject.Factory.newInstance(); |
| d = y.newCursor(); |
| d.toNextToken(); |
| x.newCursor().moveXmlContents(d); |
| assertEquals("<foo x=\"y\">abc</foo>", y.xmlText()); |
| |
| x = XmlObject.Factory.parse("<bar><foo x='y'>abc</foo></bar>"); |
| y = XmlObject.Factory.newInstance(); |
| c = x.newCursor(); |
| c.toNextToken(); |
| d = y.newCursor(); |
| d.toNextToken(); |
| c.moveXmlContents(d); |
| assertEquals("<foo x=\"y\">abc</foo>", y.xmlText()); |
| |
| x = XmlObject.Factory.parse("<bar><foo x='y'>abc</foo></bar>"); |
| c = x.newCursor(); |
| c.toNextToken(); |
| c.removeXmlContents(); |
| assertEquals("<bar/>", x.xmlText()); |
| |
| x = XmlObject.Factory.parse("<foo x='y'>abc</foo>"); |
| y = XmlObject.Factory.newInstance(); |
| d = y.newCursor(); |
| d.toNextToken(); |
| x.newCursor().copyXmlContents(d); |
| assertEquals("<foo x=\"y\">abc</foo>", y.xmlText()); |
| } |
| |
| private static class Anno extends XmlBookmark { |
| } |
| |
| @Test |
| public void testSave() throws Exception { |
| XmlObject x; |
| XmlCursor cTo; |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>abcdef</foo>"); |
| |
| assertEquals("<foo>abcdef</foo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo>a<b&c</foo>"); |
| |
| assertEquals("<foo>a<b&c</foo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo></foo>"); |
| |
| cTo = navDoc(x, "dt"); |
| cTo.insertChars("&<"); |
| |
| assertEquals("<foo>&<</foo>", x.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo><boo>bar</boo></foo>"); |
| |
| cTo = navDoc(x, "dt"); |
| |
| assertEquals("<boo>bar</boo>", cTo.xmlText()); |
| |
| // |
| |
| x = XmlObject.Factory.parse("<foo><boo x=\"y\">bar</boo></foo>"); |
| |
| cTo = navDoc(x, "dt"); |
| |
| assertEquals("<boo x=\"y\">bar</boo>", cTo.xmlText()); |
| |
| // Tests fragment saving and loading |
| |
| x = XmlObject.Factory.parse("<foo>Eric</foo>"); |
| |
| cTo = navDoc(x, "dt"); |
| |
| x = XmlObject.Factory.parse(cTo.xmlText()); |
| |
| cTo = navDoc(x, ""); |
| |
| assertEquals("Eric", cTo.getTextValue()); |
| |
| // test save where I replace the name of an element |
| |
| x = XmlObject.Factory.parse("<foo>Eric</foo>"); |
| |
| cTo = navDoc(x, "d"); |
| |
| XmlOptions options = new XmlOptions(); |
| |
| options.put( |
| XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT, |
| new QName(null, "bar")); |
| |
| x = XmlObject.Factory.parse(cTo.xmlText(options)); |
| |
| cTo = navDoc(x, ""); |
| |
| assertEquals("<bar>Eric</bar>", cTo.xmlText()); |
| |
| // test save where I replace the name of the document |
| |
| x = XmlObject.Factory.parse("<foo>Eric</foo>"); |
| |
| cTo = navDoc(x, ""); |
| |
| options = new XmlOptions(); |
| |
| options.put( |
| XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT, |
| new QName(null, "bar")); |
| |
| x = XmlObject.Factory.parse(cTo.xmlText(options)); |
| |
| cTo = navDoc(x, ""); |
| |
| assertEquals("<bar><foo>Eric</foo></bar>", cTo.xmlText()); |
| |
| x = XmlObject.Factory.parse("<a xmlns='foo'/>"); |
| |
| XmlCursor c = x.newCursor(); |
| |
| c.toFirstContentToken(); |
| c.toFirstContentToken(); |
| |
| c.insertElement("b"); |
| c.toPrevSibling(); |
| assertEquals("b", c.getName().getLocalPart()); |
| assertEquals(0, c.getName().getNamespaceURI().length()); |
| |
| x = XmlObject.Factory.parse(x.xmlText()); |
| |
| c = x.newCursor(); |
| |
| c.toFirstContentToken(); |
| c.toFirstContentToken(); |
| |
| assertEquals("b", c.getName().getLocalPart()); |
| assertEquals(0, c.getName().getNamespaceURI().length()); |
| } |
| |
| private void testTextFrag(String actual, String expected) { |
| String pre = "<xml-fragment>"; |
| |
| String post = "</xml-fragment>"; |
| |
| assertTrue(actual.startsWith(pre)); |
| assertTrue(actual.endsWith(post)); |
| |
| assertEquals(expected, actual.substring( |
| pre.length(), actual.length() - post.length())); |
| } |
| |
| @Test |
| public void testSaveFrag() { |
| XmlObject x; |
| XmlCursor c; |
| |
| x = XmlObject.Factory.newInstance(); |
| |
| c = x.newCursor(); |
| |
| c.toNextToken(); |
| |
| c.insertChars("Eric"); |
| |
| testTextFrag(x.xmlText(), "Eric"); |
| |
| // |
| |
| x = XmlObject.Factory.newInstance(); |
| |
| c = x.newCursor(); |
| |
| c.toNextToken(); |
| |
| c.insertComment(""); |
| c.insertChars("x"); |
| |
| testTextFrag(x.xmlText(), "<!---->x"); |
| |
| // |
| |
| x = XmlObject.Factory.newInstance(); |
| |
| c = x.newCursor(); |
| |
| c.toNextToken(); |
| |
| c.insertElement("foo"); |
| c.insertChars("x"); |
| |
| testTextFrag(x.xmlText(), "<foo/>x"); |
| |
| // |
| |
| x = XmlObject.Factory.newInstance(); |
| |
| c = x.newCursor(); |
| |
| c.toNextToken(); |
| |
| c.insertElement("foo"); |
| c.insertElement("bar"); |
| |
| testTextFrag(x.xmlText(), "<foo/><bar/>"); |
| } |
| |
| @Test |
| public void testLoad() throws Exception { |
| XmlObject x; |
| |
| XmlOptions options = new XmlOptions(); |
| |
| options.put(XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT, null); |
| |
| x = |
| XmlObject.Factory.parse( |
| "<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>", options); |
| |
| XmlCursor c = navDoc(x, "t"); |
| |
| assertSame(c.currentTokenType(), TokenType.ATTR); |
| |
| String open = "xmlns:open='http://www.openuri.org/fragment'"; |
| |
| x = |
| XmlObject.Factory.parse( |
| "<open:fragment p='q' x='y' " + open + |
| ">ab<foo>xy</foo>cd</open:fragment>"); |
| |
| c = navDoc(x, "t"); |
| |
| assertSame(c.currentTokenType(), TokenType.ATTR); |
| } |
| |
| @Test |
| public void testCompare() throws Exception { |
| XmlObject x; |
| XmlCursor cFrom, cTo; |
| |
| // Forward navigation |
| |
| x = XmlObject.Factory.parse("<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>"); |
| |
| cFrom = navDoc(x, ""); |
| cTo = navDoc(x, ""); |
| |
| for (; ; ) { |
| assertEquals(0, cFrom.comparePosition(cTo)); |
| assertTrue(cFrom.isAtSamePositionAs(cTo)); |
| |
| TokenType tt = cFrom.currentTokenType(); |
| |
| if (tt == TokenType.ENDDOC) { |
| break; |
| } else if (tt == TokenType.TEXT) { |
| cFrom.toNextChar(1); |
| cTo.toNextChar(1); |
| } else { |
| cFrom.toNextToken(); |
| cTo.toNextToken(); |
| } |
| } |
| |
| // Backward navigation |
| |
| x = XmlObject.Factory.parse("<bar p='q' x='y'>ab<foo>xy</foo>cd</bar>"); |
| |
| cFrom = navDoc(x, "r"); |
| cTo = navDoc(x, "r"); |
| |
| for (; ; ) { |
| assertEquals(0, cFrom.comparePosition(cTo)); |
| assertTrue(cFrom.isAtSamePositionAs(cTo)); |
| |
| if (cFrom.toPrevChar(1) == 1) |
| cTo.toPrevChar(1); |
| else if (cFrom.toPrevToken() != TokenType.NONE) |
| cTo.toPrevToken(); |
| else |
| break; |
| } |
| |
| // |
| |
| x = XmlObject.Factory.parse( |
| "<bar p='q' x='y'>ab<foo>xy</foo>c<f y='x'>xy</f>d</bar>"); |
| |
| cFrom = navDoc(x, ""); |
| |
| for (; ; ) { |
| boolean passed = false; |
| |
| cTo = navDoc(x, ""); |
| |
| for (; ; ) { |
| if (cTo.isAtSamePositionAs(cFrom)) { |
| assertTrue(!passed); |
| passed = true; |
| } else if (cTo.isLeftOf(cFrom)) { |
| assertTrue(!passed); |
| } else { |
| assertTrue(passed); |
| assertTrue(cTo.isRightOf(cFrom)); |
| } |
| |
| if (cTo.toNextChar(1) != 1) |
| if (cTo.toNextToken() == TokenType.ENDDOC) |
| break; |
| } |
| |
| if (cFrom.toNextChar(1) != 1) |
| if (cFrom.toNextToken() == TokenType.ENDDOC) |
| break; |
| } |
| } |
| |
| @Test |
| public void testAttrSetter() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<foo/>"); |
| XmlCursor c = x.newCursor(); |
| c.toNextToken(); |
| c.setAttributeText(new QName(null, "x"), "hardehar"); |
| assertEquals("<foo x=\"hardehar\"/>", x.xmlText()); |
| } |
| |
| @Test |
| public void testNavigation() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<a><x/><y/><z/></a>"); |
| XmlCursor c = x.newCursor(); |
| assertFalse(c.toNextSibling()); |
| assertFalse(c.toPrevSibling()); |
| assertFalse(c.toFirstAttribute()); |
| assertFalse(c.toLastAttribute()); |
| c.toNextToken(); |
| c.toNextToken(); |
| assertTrue(c.toNextSibling()); |
| assertEquals("y", c.getName().getLocalPart()); |
| assertTrue(c.toNextSibling()); |
| assertEquals("z", c.getName().getLocalPart()); |
| assertFalse(c.toNextSibling()); |
| |
| x = XmlObject.Factory.parse("<a p='q' m='n'><x/><y/><z/></a>"); |
| c = x.newCursor(); |
| c.toNextToken(); |
| c.toNextToken(); |
| assertTrue(c.currentTokenType().isAttr()); |
| assertFalse(c.toPrevSibling()); |
| assertTrue(c.currentTokenType().isAttr()); |
| assertTrue(c.toNextSibling()); |
| assertEquals("x", c.getName().getLocalPart()); |
| |
| c.toEndDoc(); |
| c.toPrevToken(); |
| assertTrue(c.toPrevSibling()); |
| assertEquals("z", c.getName().getLocalPart()); |
| assertTrue(c.toPrevSibling()); |
| assertEquals("y", c.getName().getLocalPart()); |
| assertTrue(c.toPrevSibling()); |
| assertEquals("x", c.getName().getLocalPart()); |
| assertFalse(c.toPrevSibling()); |
| |
| c.toEndDoc(); |
| c.toPrevToken(); |
| assertTrue(c.toParent()); |
| assertEquals("a", c.getName().getLocalPart()); |
| |
| c.toEndDoc(); |
| assertTrue(c.toParent()); |
| assertTrue(c.currentTokenType().isStartdoc()); |
| |
| x = XmlObject.Factory.parse("<a>moo<!---->foo</a>"); |
| c = x.newCursor(); |
| c.toStartDoc(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextToken(); |
| assertTrue(c.toParent()); |
| assertEquals("a", c.getName().getLocalPart()); |
| |
| c.toStartDoc(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextToken(); |
| assertTrue(c.toParent()); |
| assertEquals("a", c.getName().getLocalPart()); |
| |
| c.toStartDoc(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextChar(2); |
| assertTrue(c.toParent()); |
| assertEquals("a", c.getName().getLocalPart()); |
| |
| x = XmlObject.Factory.parse("<foo>early<bar>text<char>zap</char></bar></foo>"); |
| c = x.newCursor(); |
| c.toNextToken(); |
| c.toNextToken(); |
| assertTrue(c.toFirstChild()); |
| assertEquals("zap", c.getTextValue()); |
| } |
| |
| @Test |
| public void testGetName() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<a x='y'>eric<!----><?moo?></a>"); |
| XmlCursor c = x.newCursor(); |
| assertNull(c.getName()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertEquals("a", c.getName().getLocalPart()); |
| assertEquals(0, c.getName().getNamespaceURI().length()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertEquals("x", c.getName().getLocalPart()); |
| assertEquals(0, c.getName().getNamespaceURI().length()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertNull(c.getName()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertNull(c.getName()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertEquals("moo", c.getName().getLocalPart()); |
| assertEquals(0, c.getName().getNamespaceURI().length()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertNull(c.getName()); |
| assertTrue(!c.toNextToken().isNone()); |
| assertNull(c.getName()); |
| assertTrue(c.toNextToken().isNone()); |
| } |
| |
| @Test |
| public void testGetChars() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse("<foo>abcdefghijkl</foo>"); |
| XmlCursor c = x.newCursor(); |
| c.toNextToken(); |
| c.toNextToken(); |
| c.toNextChar(2); |
| |
| char[] buf = new char[3]; |
| int n = c.getChars(buf, 0, 400); |
| |
| assertEquals(3, n); |
| assertEquals('c', buf[0]); |
| assertEquals('d', buf[1]); |
| assertEquals('e', buf[2]); |
| } |
| |
| @Test |
| public void testNamespaceSubstitution() |
| throws Exception { |
| HashMap<String, String> subs = new HashMap<String, String>(); |
| subs.put("foo", "moo"); |
| subs.put("a", "b"); |
| |
| XmlOptions options = new XmlOptions(); |
| options.put(XmlOptions.LOAD_SUBSTITUTE_NAMESPACES, subs); |
| |
| XmlObject x = |
| XmlObject.Factory.parse( |
| "<a xmlns='foo' xmlns:a='a' a:x='y'/>", |
| options); |
| |
| XmlCursor c = x.newCursor(); |
| |
| c.toNextToken(); |
| assertEquals("moo", c.getName().getNamespaceURI()); |
| |
| c.toNextToken(); |
| assertEquals("moo", c.getName().getNamespaceURI()); |
| |
| c.toNextToken(); |
| assertEquals("b", c.getName().getNamespaceURI()); |
| |
| c.toNextToken(); |
| assertEquals("b", c.getName().getNamespaceURI()); |
| } |
| |
| @Test |
| public void testNamespaceInsertion() |
| throws Exception { |
| XmlObject x = XmlObject.Factory.newInstance(); |
| |
| XmlCursor c = x.newCursor(); |
| |
| c.toNextToken(); |
| c.insertElement("foo", "http://p.com"); |
| c.toPrevToken(); |
| c.insertNamespace("p", "http://p.com"); |
| |
| assertEquals("<p:foo xmlns:p=\"http://p.com\"/>", x.xmlText()); |
| } |
| |
| private void dotestParser(String xml, String xmlResult) |
| throws Exception { |
| XmlObject x = XmlObject.Factory.parse(xml); |
| String result = x.xmlText(); |
| assertEquals(xmlResult, result); |
| } |
| |
| private void dotestParserErrors(String xml) { |
| try { |
| XmlObject.Factory.parse(xml); |
| } catch (Throwable t) { |
| return; |
| } |
| |
| fail(); |
| } |
| |
| @Test |
| public void testNil() |
| throws Exception { |
| XmlObject x = noNamespace.CanBeNilDocument.Factory.parse("<canBeNil/>"); |
| XmlCursor c = x.newCursor(); |
| c.toFirstChild(); |
| XmlObject fc = c.getObject(); |
| assertTrue(!fc.isNil()); |
| fc.setNil(); |
| assertTrue(fc.isNil()); |
| assertEquals("<canBeNil xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>", x.xmlText()); |
| c.toNextToken(); |
| assertTrue(c.isAttr()); |
| c.removeXml(); |
| assertEquals("<canBeNil/>", x.xmlText()); |
| assertTrue(!fc.isNil()); |
| } |
| |
| @Test |
| public void testParser() |
| throws Exception { |
| dotestParserErrors("<hee yee='five'><haw>66</haw></any>"); |
| dotestParserErrors("<foo></moo>"); |
| dotestParserErrors("<a><foo></moo></a>"); |
| dotestParserErrors(""); |
| dotestParserErrors(" "); |
| |
| dotestParserErrors("har"); |
| dotestParserErrors("<!-- comment -->"); |
| dotestParserErrors("<?moo?>"); |
| dotestParserErrors("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); |
| dotestParserErrors("<a$/>"); |
| dotestParserErrors("<foo a='<'></foo>"); |
| dotestParserErrors("<foo a></foo>"); |
| dotestParserErrors("<foo>"); |
| dotestParserErrors("</foo>"); |
| dotestParserErrors( "<foo><!-- -- --></foo>" ); |
| dotestParserErrors( "<foo><!-- ---></foo>" ); |
| |
| dotestParser("<a b=\"x\n\ny\"/>", "<a b=\"x y\"/>"); |
| } |
| |
| @Test |
| public void testSaxParser() |
| throws Exception { |
| String xml = "<a x='y'><!---->x<b/><c p='q'>z</c></a>"; |
| |
| SAXParserFactory spf = SAXParserFactory.newInstance(); |
| SAXParser sp = spf.newSAXParser(); |
| XMLReader xr = sp.getXMLReader(); |
| InputSource is = new InputSource(new StringReader(xml)); |
| XmlSaxHandler sh = XmlObject.Factory.newXmlSaxHandler(); |
| |
| xr.setFeature( |
| "http://xml.org/sax/features/namespace-prefixes", |
| true); |
| |
| xr.setFeature( |
| "http://xml.org/sax/features/namespaces", true); |
| |
| xr.setFeature( |
| "http://xml.org/sax/features/validation", false); |
| |
| xr.setContentHandler(sh.getContentHandler()); |
| |
| xr.setProperty( |
| "http://xml.org/sax/properties/lexical-handler", |
| sh.getLexicalHandler()); |
| |
| xr.parse(is); |
| |
| XmlObject x1 = sh.getObject(); |
| |
| XmlObject x2 = XmlObject.Factory.parse(xml); |
| |
| assertEquals(x1.xmlText(), x2.xmlText()); |
| } |
| |
| @Test |
| public void testAdditionalNamespaces() |
| throws Exception { |
| String xml = "<a xmlns:a='aNS'><a:b/></a>"; |
| |
| Map<String, String> map = new java.util.LinkedHashMap<String, String>(); |
| map.put("b", "bNS"); |
| map.put("c", "cNS"); |
| map.put("a", "not-aNS"); |
| |
| XmlOptions options = new XmlOptions(); |
| options.setLoadAdditionalNamespaces(map); |
| |
| XmlObject x = XmlObject.Factory.parse(xml, options); |
| |
| // 'a' prefix namespace is not remapped |
| |
| xml = "<a xmlns='aNS'><b/></a>"; |
| |
| map = new java.util.LinkedHashMap<String, String>(); |
| map.put("b", "bNS"); |
| map.put("c", "cNS"); |
| map.put("", "not-aNS"); |
| |
| options = new XmlOptions(); |
| options.setLoadAdditionalNamespaces(map); |
| |
| x = XmlObject.Factory.parse(xml, options); |
| |
| // default namespace is not remapped |
| String expect = "<a xmlns=\"aNS\" xmlns:b=\"bNS\" xmlns:c=\"cNS\"><b/></a>"; |
| assertEquals(expect, x.xmlText()); |
| |
| } |
| |
| |
| } |