You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2075 lines
83 KiB
2075 lines
83 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2005 Ariya Hidayat <ariya@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
*/
|
|
|
|
// xmlreadertest.cpp - test KoXml classes
|
|
// Ariya Hidayat, November 2005
|
|
|
|
#include <qstring.h>
|
|
#include <qcstring.h>
|
|
#include <qbuffer.h>
|
|
#include <qtextstream.h>
|
|
#include <qdatetime.h>
|
|
#include <qfile.h>
|
|
|
|
#include "KoXmlReader.h"
|
|
#include <qxml.h>
|
|
|
|
#define CHECK(x,y) check(__FILE__,__LINE__,#x,x,y)
|
|
|
|
static int testCount = 0;
|
|
static int testFailed = 0;
|
|
|
|
template<typename T>
|
|
void check( const char *file, int line, const char* msg,
|
|
const T& result, const T& expected )
|
|
{
|
|
testCount++;
|
|
if( result != expected )
|
|
{
|
|
testFailed++;
|
|
QString message;
|
|
QTextStream ts( &message, IO_WriteOnly );
|
|
ts << msg;
|
|
ts << " Result:";
|
|
ts << result;
|
|
ts << ", ";
|
|
ts << "Expected:";
|
|
ts << expected;
|
|
printf( "%s [%d]: %s\n", file, line, message.latin1() );
|
|
}
|
|
}
|
|
|
|
void check( const char *file, int line, const char* msg, bool result,
|
|
bool expected )
|
|
{
|
|
testCount++;
|
|
if( result != expected )
|
|
{
|
|
testFailed++;
|
|
QString message;
|
|
QTextStream ts( &message, IO_WriteOnly );
|
|
ts << msg;
|
|
ts << " Result: ";
|
|
if( result ) ts << "True"; else ts << "False";
|
|
ts << ", ";
|
|
ts << "Expected: ";
|
|
if( expected ) ts << "True"; else ts << "False";
|
|
printf( "%s [%d]: %s\n", file, line, message.latin1() );
|
|
}
|
|
}
|
|
|
|
void testNode()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<earth>";
|
|
xmlstream << "<continents>";
|
|
xmlstream << "<asia/>";
|
|
xmlstream << "<africa/>";
|
|
xmlstream << "<europe/>";
|
|
xmlstream << "<america/>";
|
|
xmlstream << "<australia/>";
|
|
xmlstream << "<antartic/>";
|
|
xmlstream << "</continents>";
|
|
xmlstream << "<oceans>";
|
|
xmlstream << "<pacific/>";
|
|
xmlstream << "<atlantic/>";
|
|
xmlstream << "</oceans>";
|
|
xmlstream << "</earth>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
// null node
|
|
KoXmlNode node1;
|
|
CHECK( node1.nodeName(), QString::null );
|
|
CHECK( node1.isNull(), true );
|
|
CHECK( node1.isElement(), false );
|
|
CHECK( node1.isElement(), false );
|
|
CHECK( node1.isDocument(), false );
|
|
CHECK( node1.ownerDocument().isNull(), false );
|
|
CHECK( node1.parentNode().isNull(), true );
|
|
CHECK( node1.hasChildNodes(), false );
|
|
CHECK( node1.firstChild().isNull(), true );
|
|
CHECK( node1.lastChild().isNull(), true );
|
|
CHECK( node1.previousSibling().isNull(), true );
|
|
CHECK( node1.nextSibling().isNull(), true );
|
|
|
|
// compare with another null node
|
|
KoXmlNode node2;
|
|
CHECK( node2.isNull(), true );
|
|
CHECK( node1==node2, true );
|
|
CHECK( node1!=node2, false );
|
|
|
|
// a node which is a document
|
|
KoXmlNode node3 = doc;
|
|
CHECK( node3.nodeName(), QString("#document") );
|
|
CHECK( node3.isNull(), false );
|
|
CHECK( node3.isElement(), false );
|
|
CHECK( node3.isText(), false );
|
|
CHECK( node3.isDocument(), true );
|
|
CHECK( node3.ownerDocument().isNull(), false );
|
|
CHECK( node3.ownerDocument()==doc, true );
|
|
CHECK( node3.toDocument()==doc, true );
|
|
|
|
// convert to document and the compare
|
|
KoXmlDocument doc2 = node3.toDocument();
|
|
CHECK( doc2.nodeName(), QString("#document") );
|
|
CHECK( doc2.isNull(), false );
|
|
CHECK( doc2.isDocument(), true );
|
|
CHECK( node3==doc2, true );
|
|
|
|
// a document is of course can't be converted to element
|
|
KoXmlElement invalidElement = node3.toElement();
|
|
CHECK( invalidElement.nodeName(), QString::null );
|
|
CHECK( invalidElement.isNull(), true );
|
|
CHECK( invalidElement.isElement(), true );
|
|
CHECK( invalidElement.isText(), false );
|
|
CHECK( invalidElement.isDocument(), false );
|
|
|
|
// clear() makes it a null node again
|
|
node3.clear();
|
|
CHECK( node3.isNull(), true );
|
|
CHECK( node3.nodeName(), QString::null );
|
|
CHECK( node3.isElement(), false );
|
|
CHECK( node3.isText(), false );
|
|
CHECK( node3.isDocument(), false );
|
|
CHECK( node3.ownerDocument().isNull(), false );
|
|
CHECK( node1==node3, true );
|
|
CHECK( node1!=node3, false );
|
|
|
|
// a node which is an element for <earth>
|
|
KoXmlNode node4 = doc.firstChild();
|
|
CHECK( node4.isNull(), false );
|
|
CHECK( node4.isElement(), true );
|
|
CHECK( node4.isText(), false );
|
|
CHECK( node4.isDocument(), false );
|
|
CHECK( node4.hasChildNodes(), true );
|
|
CHECK( node4.ownerDocument()==doc, true );
|
|
CHECK( node4.toElement()==doc.firstChild().toElement(), true );
|
|
|
|
// clear() makes it a null node again
|
|
node4.clear();
|
|
CHECK( node4.isNull(), true );
|
|
CHECK( node4.isElement(), false );
|
|
CHECK( node4.isText(), false );
|
|
CHECK( node4.isDocument(), false );
|
|
CHECK( node4==node1, true );
|
|
CHECK( node4!=node1, false );
|
|
|
|
// a node which is an element for <continents>
|
|
KoXmlNode node5 = doc.firstChild().firstChild();
|
|
CHECK( node5.nodeName(), QString("continents") );
|
|
CHECK( node5.isNull(), false );
|
|
CHECK( node5.isElement(), true );
|
|
CHECK( node5.isText(), false );
|
|
CHECK( node5.isDocument(), false );
|
|
CHECK( node5.hasChildNodes(), true );
|
|
CHECK( node5.ownerDocument()==doc, true );
|
|
|
|
// convert to element and the compare
|
|
KoXmlElement continentsElement = node5.toElement();
|
|
CHECK( node5==continentsElement, true );
|
|
CHECK( continentsElement.isNull(), false );
|
|
CHECK( continentsElement.isElement(), true );
|
|
CHECK( continentsElement.isText(), false );
|
|
CHECK( continentsElement.hasChildNodes(), true );
|
|
CHECK( continentsElement.ownerDocument()==doc, true );
|
|
|
|
// and it doesn't make sense to convert that node to document
|
|
// (instead a brand new document is created, i.e. not a null node)
|
|
KoXmlDocument invalidDoc = node5.toDocument();
|
|
CHECK( invalidDoc.isNull(), false );
|
|
CHECK( invalidDoc.isElement(), false );
|
|
CHECK( invalidDoc.isText(), false );
|
|
CHECK( invalidDoc.isDocument(), true );
|
|
|
|
// node for <europe> using namedItem() function
|
|
KoXmlNode europeNode = continentsElement.namedItem( QString("europe") );
|
|
CHECK( europeNode.nodeName(), QString("europe") );
|
|
CHECK( europeNode.isNull(), false );
|
|
CHECK( europeNode.isElement(), true );
|
|
CHECK( europeNode.isText(), false );
|
|
CHECK( europeNode.hasChildNodes(), false );
|
|
CHECK( europeNode.ownerDocument()==doc, true );
|
|
|
|
// search non-existing node
|
|
KoXmlNode fooNode = continentsElement.namedItem( QString("foobar") );
|
|
CHECK( fooNode.isNull(), true );
|
|
CHECK( fooNode.isElement(), false );
|
|
CHECK( fooNode.isText(), false );
|
|
CHECK( fooNode.isCDATASection(), false );
|
|
}
|
|
|
|
void testElement()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<html>";
|
|
xmlstream << "<body bgcolor=\"#000\">";
|
|
xmlstream << "<p>";
|
|
xmlstream << "Hello, world!";
|
|
xmlstream << "</p>";
|
|
xmlstream << "</body>";
|
|
xmlstream << "</html>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
// element for <html>
|
|
KoXmlElement rootElement;
|
|
rootElement = doc.documentElement();
|
|
CHECK( rootElement.nodeName(), QString("html") );
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.isDocument(), false );
|
|
CHECK( rootElement.ownerDocument().isNull(), false );
|
|
CHECK( rootElement.ownerDocument()==doc, true );
|
|
CHECK( rootElement.parentNode().isNull(), false );
|
|
CHECK( rootElement.parentNode().toDocument()==doc, true );
|
|
CHECK( rootElement.hasChildNodes(), true );
|
|
CHECK( rootElement.tagName(), QString("html") );
|
|
CHECK( rootElement.prefix().isNull(), true );
|
|
|
|
// element for <body>
|
|
KoXmlElement bodyElement;
|
|
bodyElement = rootElement.firstChild().toElement();
|
|
CHECK( bodyElement.nodeName(), QString("body") );
|
|
CHECK( bodyElement.isNull(), false );
|
|
CHECK( bodyElement.isElement(), true );
|
|
CHECK( bodyElement.isDocument(), false );
|
|
CHECK( bodyElement.ownerDocument().isNull(), false );
|
|
CHECK( bodyElement.ownerDocument()==doc, true );
|
|
CHECK( bodyElement.parentNode().isNull(), false );
|
|
CHECK( bodyElement.parentNode()==rootElement, true );
|
|
CHECK( bodyElement.hasChildNodes(), true );
|
|
CHECK( bodyElement.tagName(), QString("body") );
|
|
CHECK( bodyElement.prefix().isNull(), true );
|
|
CHECK( bodyElement.hasAttribute("bgcolor"), true );
|
|
CHECK( bodyElement.attribute("bgcolor"), QString("#000") );
|
|
|
|
// a shared copy of <body>, will still have access to attribute bgcolor
|
|
KoXmlElement body2Element;
|
|
body2Element = bodyElement;
|
|
CHECK( body2Element.nodeName(), QString("body") );
|
|
CHECK( body2Element.isNull(), false );
|
|
CHECK( body2Element.isElement(), true );
|
|
CHECK( body2Element.isDocument(), false );
|
|
CHECK( body2Element.ownerDocument().isNull(), false );
|
|
CHECK( body2Element.ownerDocument()==doc, true );
|
|
CHECK( body2Element==bodyElement, true );
|
|
CHECK( body2Element!=bodyElement, false );
|
|
CHECK( body2Element.hasChildNodes(), true );
|
|
CHECK( body2Element.tagName(), QString("body") );
|
|
CHECK( body2Element.prefix().isNull(), true );
|
|
CHECK( body2Element.hasAttribute("bgcolor"), true );
|
|
CHECK( body2Element.attribute("bgcolor"), QString("#000") );
|
|
|
|
// empty element, by default constructor
|
|
KoXmlElement testElement;
|
|
CHECK( testElement.nodeName(), QString::null );
|
|
CHECK( testElement.isNull(), true );
|
|
CHECK( testElement.isElement(), true );
|
|
CHECK( testElement.isDocument(), false );
|
|
CHECK( testElement.ownerDocument().isNull(), false );
|
|
CHECK( testElement.ownerDocument()!=doc, true );
|
|
CHECK( testElement==rootElement, false );
|
|
CHECK( testElement!=rootElement, true );
|
|
CHECK( testElement.parentNode().isNull(), true );
|
|
CHECK( testElement.hasChildNodes(), false );
|
|
|
|
// check assignment operator
|
|
testElement = rootElement;
|
|
CHECK( testElement.nodeName(), QString("html") );
|
|
CHECK( testElement.isNull(), false );
|
|
CHECK( testElement.isElement(), true );
|
|
CHECK( testElement.isDocument(), false );
|
|
CHECK( testElement==rootElement, true );
|
|
CHECK( testElement!=rootElement, false );
|
|
CHECK( testElement.parentNode().isNull(), false );
|
|
CHECK( testElement.parentNode().toDocument()==doc, true );
|
|
CHECK( testElement.tagName(), QString("html") );
|
|
CHECK( testElement.prefix().isNull(), true );
|
|
|
|
// assigned from another empty element
|
|
testElement = KoXmlElement();
|
|
CHECK( testElement.isNull(), true );
|
|
CHECK( testElement!=rootElement, true );
|
|
|
|
// assigned from <body>
|
|
testElement = bodyElement;
|
|
CHECK( testElement.isNull(), false );
|
|
CHECK( testElement.isElement(), true );
|
|
CHECK( testElement.isDocument(), false );
|
|
CHECK( testElement.ownerDocument().isNull(), false );
|
|
CHECK( testElement.ownerDocument()==doc, true );
|
|
CHECK( testElement==bodyElement, true );
|
|
CHECK( testElement.parentNode().isNull(), false );
|
|
CHECK( testElement.tagName(), QString("body") );
|
|
CHECK( testElement.prefix().isNull(), true );
|
|
CHECK( testElement.hasChildNodes(), true );
|
|
|
|
// copy constructor
|
|
KoXmlElement dummyElement( rootElement );
|
|
CHECK( dummyElement.isNull(), false );
|
|
CHECK( dummyElement.isElement(), true );
|
|
CHECK( dummyElement.isDocument(), false );
|
|
CHECK( dummyElement.ownerDocument().isNull(), false );
|
|
CHECK( dummyElement.ownerDocument()==doc, true );
|
|
CHECK( dummyElement==rootElement, true );
|
|
CHECK( dummyElement.parentNode().isNull(), false );
|
|
CHECK( dummyElement.hasChildNodes(), true );
|
|
CHECK( dummyElement.tagName(), QString("html") );
|
|
CHECK( dummyElement.prefix().isNull(), true );
|
|
|
|
// clear() turns element to null node
|
|
dummyElement.clear();
|
|
CHECK( dummyElement.isNull(), true );
|
|
CHECK( dummyElement.isElement(), true );
|
|
CHECK( dummyElement.isDocument(), false );
|
|
CHECK( dummyElement.ownerDocument().isNull(), false );
|
|
CHECK( dummyElement.ownerDocument()==doc, false );
|
|
CHECK( dummyElement.hasChildNodes(), false );
|
|
CHECK( dummyElement==rootElement, false );
|
|
CHECK( dummyElement!=rootElement, true );
|
|
|
|
// check for plain null node converted to element
|
|
KoXmlNode dummyNode;
|
|
dummyElement = dummyNode.toElement();
|
|
CHECK( dummyElement.isNull(), true );
|
|
CHECK( dummyElement.isElement(), true );
|
|
CHECK( dummyElement.isDocument(), false );
|
|
CHECK( dummyElement.ownerDocument().isNull(), false );
|
|
CHECK( dummyElement.hasChildNodes(), false );
|
|
CHECK( dummyElement.ownerDocument()==doc, false );
|
|
}
|
|
|
|
void testAttributes()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<p>";
|
|
xmlstream << "<img src=\"foo.png\" width=\"300\" height=\"150\"/>";
|
|
xmlstream << "</p>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
KoXmlElement rootElement;
|
|
rootElement = doc.documentElement();
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.parentNode().isNull(), false );
|
|
CHECK( rootElement.parentNode().toDocument()==doc, true );
|
|
CHECK( rootElement.tagName(), QString("p") );
|
|
CHECK( rootElement.prefix().isNull(), true );
|
|
|
|
KoXmlElement imgElement;
|
|
imgElement = rootElement.firstChild().toElement();
|
|
CHECK( imgElement.isNull(), false );
|
|
CHECK( imgElement.isElement(), true );
|
|
CHECK( imgElement.tagName(), QString("img") );
|
|
CHECK( imgElement.prefix().isNull(), true );
|
|
CHECK( imgElement.hasAttribute("src"), true );
|
|
CHECK( imgElement.hasAttribute("width"), true );
|
|
CHECK( imgElement.hasAttribute("height"), true );
|
|
CHECK( imgElement.hasAttribute("non-exist"), false );
|
|
CHECK( imgElement.hasAttribute("SRC"), false );
|
|
CHECK( imgElement.attribute("src"), QString("foo.png") );
|
|
CHECK( imgElement.attribute("width"), QString("300") );
|
|
CHECK( imgElement.attribute("width").toInt(), 300 );
|
|
CHECK( imgElement.attribute("height"), QString("150") );
|
|
CHECK( imgElement.attribute("height").toInt(), 150 );
|
|
CHECK( imgElement.attribute("border").isEmpty(), true );
|
|
CHECK( imgElement.attribute("border","0").toInt(), 0 );
|
|
CHECK( imgElement.attribute("border","-1").toInt(), -1 );
|
|
}
|
|
|
|
void testText()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<p>";
|
|
xmlstream << "Hello ";
|
|
xmlstream << "<b>world</b>";
|
|
xmlstream << "</p>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
// element for <p>
|
|
KoXmlElement parElement;
|
|
parElement = doc.documentElement();
|
|
CHECK( parElement.isNull(), false );
|
|
CHECK( parElement.isElement(), true );
|
|
CHECK( parElement.isText(), false );
|
|
CHECK( parElement.isDocument(), false );
|
|
CHECK( parElement.ownerDocument().isNull(), false );
|
|
CHECK( parElement.ownerDocument()==doc, true );
|
|
CHECK( parElement.parentNode().isNull(), false );
|
|
CHECK( parElement.parentNode().toDocument()==doc, true );
|
|
CHECK( parElement.hasChildNodes(), true );
|
|
CHECK( parElement.tagName(), QString("p") );
|
|
CHECK( parElement.prefix().isNull(), true );
|
|
CHECK( parElement.text(), QString("Hello world") );
|
|
|
|
// node for "Hello"
|
|
KoXmlNode helloNode;
|
|
helloNode = parElement.firstChild();
|
|
CHECK( helloNode.nodeName(), QString("#text") );
|
|
CHECK( helloNode.isNull(), false );
|
|
CHECK( helloNode.isElement(), false );
|
|
CHECK( helloNode.isText(), true );
|
|
CHECK( helloNode.isDocument(), false );
|
|
|
|
// "Hello" text
|
|
KoXmlText helloText;
|
|
helloText = helloNode.toText();
|
|
CHECK( helloText.nodeName(), QString("#text") );
|
|
CHECK( helloText.isNull(), false );
|
|
CHECK( helloText.isElement(), false );
|
|
CHECK( helloText.isText(), true );
|
|
CHECK( helloText.isDocument(), false );
|
|
CHECK( helloText.data(), QString("Hello ") );
|
|
|
|
// shared copy of the text
|
|
KoXmlText hello2Text;
|
|
hello2Text = helloText;
|
|
CHECK( hello2Text.isNull(), false );
|
|
CHECK( hello2Text.isElement(), false );
|
|
CHECK( hello2Text.isText(), true );
|
|
CHECK( hello2Text.isDocument(), false );
|
|
CHECK( hello2Text.data(), QString("Hello ") );
|
|
|
|
// element for <b>
|
|
KoXmlElement boldElement;
|
|
boldElement = helloNode.nextSibling().toElement();
|
|
CHECK( boldElement.isNull(), false );
|
|
CHECK( boldElement.isElement(), true );
|
|
CHECK( boldElement.isText(), false );
|
|
CHECK( boldElement.isDocument(), false );
|
|
CHECK( boldElement.ownerDocument().isNull(), false );
|
|
CHECK( boldElement.ownerDocument()==doc, true );
|
|
CHECK( boldElement.parentNode().isNull(), false );
|
|
CHECK( boldElement.hasChildNodes(), true );
|
|
CHECK( boldElement.tagName(), QString("b") );
|
|
CHECK( boldElement.prefix().isNull(), true );
|
|
|
|
// "world" text
|
|
KoXmlText worldText;
|
|
worldText = boldElement.firstChild().toText();
|
|
CHECK( worldText.isNull(), false );
|
|
CHECK( worldText.isElement(), false );
|
|
CHECK( worldText.isText(), true );
|
|
CHECK( worldText.isDocument(), false );
|
|
CHECK( worldText.data(), QString("world") );
|
|
}
|
|
|
|
void testCDATA()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<p>";
|
|
xmlstream << "Hello ";
|
|
xmlstream << "<![CDATA[world]]>";
|
|
xmlstream << "</p>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
// element for <p>
|
|
KoXmlElement parElement;
|
|
parElement = doc.documentElement();
|
|
CHECK( parElement.isNull(), false );
|
|
CHECK( parElement.isElement(), true );
|
|
CHECK( parElement.isText(), false );
|
|
CHECK( parElement.isDocument(), false );
|
|
CHECK( parElement.ownerDocument().isNull(), false );
|
|
CHECK( parElement.ownerDocument()==doc, true );
|
|
CHECK( parElement.parentNode().isNull(), false );
|
|
CHECK( parElement.parentNode().toDocument()==doc, true );
|
|
CHECK( parElement.hasChildNodes(), true );
|
|
CHECK( parElement.tagName(), QString("p") );
|
|
CHECK( parElement.prefix().isNull(), true );
|
|
CHECK( parElement.text(), QString("Hello world") );
|
|
|
|
// node for "Hello"
|
|
KoXmlNode helloNode;
|
|
helloNode = parElement.firstChild();
|
|
CHECK( helloNode.isNull(), false );
|
|
CHECK( helloNode.isElement(), false );
|
|
CHECK( helloNode.isText(), true );
|
|
CHECK( helloNode.isDocument(), false );
|
|
|
|
// "Hello" text
|
|
KoXmlText helloText;
|
|
helloText = helloNode.toText();
|
|
CHECK( helloText.isNull(), false );
|
|
CHECK( helloText.isElement(), false );
|
|
CHECK( helloText.isText(), true );
|
|
CHECK( helloText.isDocument(), false );
|
|
CHECK( helloText.data(), QString("Hello ") );
|
|
|
|
// node for CDATA "world!"
|
|
// Note: isText() is also true for CDATA
|
|
KoXmlNode worldNode;
|
|
worldNode = helloNode.nextSibling();
|
|
CHECK( worldNode.nodeName(), QString("#cdata-section") );
|
|
CHECK( worldNode.isNull(), false );
|
|
CHECK( worldNode.isElement(), false );
|
|
CHECK( worldNode.isText(), true );
|
|
CHECK( worldNode.isCDATASection(), true );
|
|
CHECK( worldNode.isDocument(), false );
|
|
|
|
// CDATA section for "world!"
|
|
// Note: isText() is also true for CDATA
|
|
KoXmlCDATASection worldCDATA;
|
|
worldCDATA = worldNode.toCDATASection();
|
|
CHECK( worldCDATA.nodeName(), QString("#cdata-section") );
|
|
CHECK( worldCDATA.isNull(), false );
|
|
CHECK( worldCDATA.isElement(), false );
|
|
CHECK( worldCDATA.isText(), true );
|
|
CHECK( worldCDATA.isCDATASection(), true );
|
|
CHECK( worldCDATA.isDocument(), false );
|
|
CHECK( worldCDATA.data(), QString("world") );
|
|
}
|
|
|
|
void testDocument()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<koffice>";
|
|
xmlstream << " <kword/>\n";
|
|
xmlstream << " <kpresenter/>\n";
|
|
xmlstream << " <krita/>\n";
|
|
xmlstream << "</koffice>";
|
|
|
|
KoXmlDocument doc;
|
|
|
|
// empty document
|
|
CHECK( doc.nodeName(), QString("#document") );
|
|
CHECK( doc.isNull(), false );
|
|
CHECK( doc.isElement(), false );
|
|
CHECK( doc.isDocument(), true );
|
|
CHECK( doc.parentNode().isNull(), true );
|
|
CHECK( doc.firstChild().isNull(), true );
|
|
CHECK( doc.lastChild().isNull(), true );
|
|
CHECK( doc.previousSibling().isNull(), true );
|
|
CHECK( doc.nextSibling().isNull(), true );
|
|
|
|
// now give something as the content
|
|
CHECK( doc.setContent(&xmldevice,&errorMsg,&errorLine,&errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
// this document has something already
|
|
CHECK( doc.nodeName(), QString("#document") );
|
|
CHECK( doc.isNull(), false );
|
|
CHECK( doc.isElement(), false );
|
|
CHECK( doc.isDocument(), true );
|
|
CHECK( doc.parentNode().isNull(), true );
|
|
CHECK( doc.firstChild().isNull(), false );
|
|
CHECK( doc.lastChild().isNull(), false );
|
|
CHECK( doc.previousSibling().isNull(), true );
|
|
CHECK( doc.nextSibling().isNull(), true );
|
|
|
|
// make sure its children are fine
|
|
KoXmlElement rootElement;
|
|
rootElement = doc.firstChild().toElement();
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.isDocument(), false );
|
|
CHECK( rootElement.parentNode().isNull(), false );
|
|
CHECK( rootElement.parentNode().toDocument()==doc, true );
|
|
rootElement = doc.lastChild().toElement();
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.isDocument(), false );
|
|
CHECK( rootElement.parentNode().isNull(), false );
|
|
CHECK( rootElement.parentNode().toDocument()==doc, true );
|
|
|
|
// clear() converts it into null node
|
|
doc.clear();
|
|
CHECK( doc.nodeName(), QString::null );
|
|
CHECK( doc.isNull(), true );
|
|
CHECK( doc.isElement(), false );
|
|
CHECK( doc.isDocument(), true );
|
|
CHECK( doc.parentNode().isNull(), true );
|
|
CHECK( doc.firstChild().isNull(), true );
|
|
CHECK( doc.lastChild().isNull(), true );
|
|
CHECK( doc.previousSibling().isNull(), true );
|
|
CHECK( doc.nextSibling().isNull(), true );
|
|
|
|
// assigned from another empty document
|
|
doc = KoXmlDocument();
|
|
CHECK( doc.nodeName(), QString("#document") );
|
|
CHECK( doc.isNull(), false );
|
|
CHECK( doc.isElement(), false );
|
|
CHECK( doc.isDocument(), true );
|
|
CHECK( doc.parentNode().isNull(), true );
|
|
}
|
|
|
|
void testNamespace()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
|
|
// taken from example in Qt documentation (xml.html)
|
|
xmlstream << "<document xmlns:book = \"http://trolltech.com/fnord/book/\"";
|
|
xmlstream << " xmlns = \"http://trolltech.com/fnord/\" >";
|
|
xmlstream << "<book>";
|
|
xmlstream << " <book:title>Practical XML</book:title>";
|
|
xmlstream << " <book:author xmlns:fnord = \"http://trolltech.com/fnord/\"";
|
|
xmlstream << " title=\"Ms\"";
|
|
xmlstream << " fnord:title=\"Goddess\"";
|
|
xmlstream << " name=\"Eris Kallisti\"/>";
|
|
xmlstream << " <chapter>";
|
|
xmlstream << " <title>A Namespace Called fnord</title>";
|
|
xmlstream << " </chapter>";
|
|
xmlstream << "</book>";
|
|
xmlstream << "</document>";
|
|
|
|
KoXmlDocument doc;
|
|
KoXmlElement rootElement;
|
|
KoXmlElement bookElement;
|
|
KoXmlElement bookTitleElement;
|
|
KoXmlElement bookAuthorElement;
|
|
|
|
// ------------- first without any namespace processing -----------
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
rootElement = doc.documentElement();
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.tagName(), QString("document") );
|
|
CHECK( rootElement.prefix().isNull(), true );
|
|
|
|
bookElement = rootElement.firstChild().toElement();
|
|
CHECK( bookElement.isNull(), false );
|
|
CHECK( bookElement.isElement(), true );
|
|
CHECK( bookElement.tagName(), QString("book") );
|
|
CHECK( bookElement.prefix().isNull(), true );
|
|
CHECK( bookElement.localName(), QString::null );
|
|
|
|
bookTitleElement = bookElement.firstChild().toElement();
|
|
CHECK( bookTitleElement.isNull(), false );
|
|
CHECK( bookTitleElement.isElement(), true );
|
|
CHECK( bookTitleElement.tagName(), QString("book:title") );
|
|
CHECK( bookTitleElement.prefix().isNull(), true );
|
|
CHECK( bookTitleElement.localName(), QString::null );
|
|
|
|
bookAuthorElement = bookTitleElement.nextSibling().toElement();
|
|
CHECK( bookAuthorElement.isNull(), false );
|
|
CHECK( bookAuthorElement.isElement(), true );
|
|
CHECK( bookAuthorElement.tagName(), QString("book:author") );
|
|
CHECK( bookAuthorElement.prefix().isNull(), true );
|
|
CHECK( bookAuthorElement.attribute("title"), QString("Ms") );
|
|
CHECK( bookAuthorElement.attribute("fnord:title"), QString("Goddess") );
|
|
CHECK( bookAuthorElement.attribute("name"), QString("Eris Kallisti") );
|
|
|
|
// ------------- now with namespace processing -----------
|
|
xmldevice.at(0); // just to rewind
|
|
|
|
CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
char* defaultNS = "http://trolltech.com/fnord/";
|
|
char* bookNS = "http://trolltech.com/fnord/book/";
|
|
char* fnordNS = "http://trolltech.com/fnord/";
|
|
|
|
// <document>
|
|
rootElement = doc.documentElement();
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.tagName(), QString("document") );
|
|
CHECK( rootElement.prefix().isEmpty(), true );
|
|
CHECK( rootElement.namespaceURI(), QString( defaultNS ) );
|
|
CHECK( rootElement.localName(), QString("document") );
|
|
|
|
// <book>
|
|
bookElement = rootElement.firstChild().toElement();
|
|
CHECK( bookElement.isNull(), false );
|
|
CHECK( bookElement.isElement(), true );
|
|
CHECK( bookElement.tagName(), QString("book") );
|
|
CHECK( bookElement.prefix().isEmpty(), true );
|
|
CHECK( bookElement.namespaceURI(), QString( defaultNS ) );
|
|
CHECK( bookElement.localName(), QString("book") );
|
|
|
|
// <book:title>
|
|
bookTitleElement = bookElement.firstChild().toElement();
|
|
CHECK( bookTitleElement.isNull(), false );
|
|
CHECK( bookTitleElement.isElement(), true );
|
|
CHECK( bookTitleElement.tagName(), QString("title") );
|
|
CHECK( bookTitleElement.prefix(), QString("book") );
|
|
CHECK( bookTitleElement.namespaceURI(), QString(bookNS) );
|
|
CHECK( bookTitleElement.localName(), QString("title") );
|
|
|
|
// another way, find it using namedItemNS()
|
|
KoXmlElement book2TitleElement;
|
|
book2TitleElement = KoXml::namedItemNS( rootElement.firstChild(), bookNS, "title" );
|
|
//book2TitleElement = bookElement.namedItemNS( bookNS, "title" ).toElement();
|
|
CHECK( book2TitleElement==bookTitleElement, true );
|
|
CHECK( book2TitleElement.isNull(), false );
|
|
CHECK( book2TitleElement.isElement(), true );
|
|
CHECK( book2TitleElement.tagName(), QString("title") );
|
|
|
|
// <book:author>
|
|
bookAuthorElement = bookTitleElement.nextSibling().toElement();
|
|
CHECK( bookAuthorElement.isNull(), false );
|
|
CHECK( bookAuthorElement.isElement(), true );
|
|
CHECK( bookAuthorElement.tagName(), QString("author") );
|
|
CHECK( bookAuthorElement.prefix(), QString("book") );
|
|
CHECK( bookAuthorElement.namespaceURI(), QString(bookNS) );
|
|
CHECK( bookAuthorElement.localName(), QString("author") );
|
|
|
|
// another way, find it using namedItemNS()
|
|
KoXmlElement book2AuthorElement;
|
|
book2AuthorElement = KoXml::namedItemNS( bookElement, bookNS, "author" );
|
|
//book2AuthorElement = bookElement.namedItemNS( bookNS, "author" ).toElement();
|
|
CHECK( book2AuthorElement==bookAuthorElement, true );
|
|
CHECK( book2AuthorElement.isNull(), false );
|
|
CHECK( book2AuthorElement.isElement(), true );
|
|
CHECK( book2AuthorElement.tagName(), QString("author") );
|
|
|
|
// attributes in <book:author>
|
|
// Note: with namespace processing, attribute's prefix is taken out and
|
|
// hence "fnord:title" will simply override "title"
|
|
// and searching attribute with prefix will give no result
|
|
CHECK( bookAuthorElement.hasAttribute("title"), true );
|
|
CHECK( bookAuthorElement.hasAttribute("fnord:title"), false );
|
|
CHECK( bookAuthorElement.hasAttribute("name"), true );
|
|
CHECK( bookAuthorElement.attribute("title"), QString("Goddess") );
|
|
CHECK( bookAuthorElement.attribute("fnord:title").isEmpty(), true );
|
|
CHECK( bookAuthorElement.attribute("name"), QString("Eris Kallisti") );
|
|
|
|
// attributes in <book:author>, with NS family of functions
|
|
// those without prefix are not accessible at all, because they do not belong
|
|
// to any namespace at all.
|
|
// Note: default namespace does not apply to attribute names!
|
|
CHECK( bookAuthorElement.hasAttributeNS(defaultNS,"title"), true );
|
|
CHECK( bookAuthorElement.hasAttributeNS(bookNS,"title"), false );
|
|
CHECK( bookAuthorElement.hasAttributeNS(fnordNS,"title"), true );
|
|
|
|
CHECK( bookAuthorElement.attributeNS(defaultNS,"title",""), QString("Goddess") );
|
|
CHECK( bookAuthorElement.attributeNS(bookNS,"title",""), QString("") );
|
|
CHECK( bookAuthorElement.attributeNS(fnordNS,"title",""), QString("Goddess") );
|
|
|
|
CHECK( bookAuthorElement.hasAttributeNS(defaultNS,"fnord:title"), false );
|
|
CHECK( bookAuthorElement.hasAttributeNS(bookNS,"fnord:title"), false );
|
|
CHECK( bookAuthorElement.hasAttributeNS(fnordNS,"fnord:title"), false );
|
|
|
|
CHECK( bookAuthorElement.hasAttributeNS(defaultNS,"name"), false );
|
|
CHECK( bookAuthorElement.hasAttributeNS(bookNS,"name"), false );
|
|
CHECK( bookAuthorElement.hasAttributeNS(fnordNS,"name"), false );
|
|
|
|
CHECK( bookAuthorElement.attributeNS(defaultNS,"name",QString::null).isEmpty(), true );
|
|
CHECK( bookAuthorElement.attributeNS(bookNS,"name",QString::null).isEmpty(), true );
|
|
CHECK( bookAuthorElement.attributeNS(fnordNS,"name",QString::null).isEmpty(), true );
|
|
}
|
|
|
|
void testUnload()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<earth>";
|
|
xmlstream << "<continents>";
|
|
xmlstream << "<asia/>";
|
|
xmlstream << "<africa/>";
|
|
xmlstream << "<europe/>";
|
|
xmlstream << "<america/>";
|
|
xmlstream << "<australia/>";
|
|
xmlstream << "<antartic/>";
|
|
xmlstream << "</continents>";
|
|
xmlstream << "<oceans>";
|
|
xmlstream << "<pacific/>";
|
|
xmlstream << "<atlantic/>";
|
|
xmlstream << "</oceans>";
|
|
xmlstream << "</earth>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
KoXmlElement earthElement;
|
|
earthElement = doc.documentElement().toElement();
|
|
CHECK( earthElement.isNull(), false );
|
|
CHECK( earthElement.isElement(), true );
|
|
CHECK( earthElement.parentNode().isNull(), false );
|
|
CHECK( earthElement.hasChildNodes(), true );
|
|
CHECK( earthElement.tagName(), QString("earth") );
|
|
CHECK( earthElement.prefix().isNull(), true );
|
|
|
|
// this ensures that all child nodes of <earth> are loaded
|
|
earthElement.firstChild();
|
|
|
|
// explicitly unload all child nodes of <earth>
|
|
KoXml::unload( earthElement );
|
|
|
|
// we should get the correct first child
|
|
KoXmlElement continentsElement = earthElement.firstChild().toElement();
|
|
CHECK( continentsElement.nodeName(), QString("continents") );
|
|
CHECK( continentsElement.isNull(), false );
|
|
CHECK( continentsElement.isElement(), true );
|
|
CHECK( continentsElement.isText(), false );
|
|
CHECK( continentsElement.isDocument(), false );
|
|
CHECK( continentsElement.hasChildNodes(), true );
|
|
|
|
// let us unload everything again
|
|
KoXml::unload( earthElement );
|
|
|
|
// we should get the correct last child
|
|
KoXmlElement oceansElement = earthElement.lastChild().toElement();
|
|
CHECK( oceansElement.nodeName(), QString("oceans") );
|
|
CHECK( oceansElement.isNull(), false );
|
|
CHECK( oceansElement.isElement(), true );
|
|
CHECK( oceansElement.isText(), false );
|
|
CHECK( oceansElement.isDocument(), false );
|
|
CHECK( oceansElement.hasChildNodes(), true );
|
|
}
|
|
|
|
void testSimpleXML()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<solarsystem>";
|
|
xmlstream << " <mercurius/>\n";
|
|
xmlstream << " <venus/>\n";
|
|
xmlstream << " <earth>\n";
|
|
xmlstream << " <moon/>\n";
|
|
xmlstream << " </earth>\n";
|
|
xmlstream << " <mars/>\n";
|
|
xmlstream << " <jupiter/>\n";
|
|
xmlstream << "</solarsystem>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent(&xmldevice,&errorMsg,&errorLine,&errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
// <solarsystem>
|
|
KoXmlElement rootElement;
|
|
rootElement = doc.documentElement();
|
|
CHECK( rootElement.isNull(), false );
|
|
CHECK( rootElement.isElement(), true );
|
|
CHECK( rootElement.parentNode().isNull(), false );
|
|
CHECK( rootElement.hasChildNodes(), true );
|
|
CHECK( rootElement.tagName(), QString("solarsystem") );
|
|
CHECK( rootElement.prefix().isNull(), true );
|
|
|
|
// node <mercurius>
|
|
KoXmlNode firstPlanetNode;
|
|
firstPlanetNode = rootElement.firstChild();
|
|
CHECK( firstPlanetNode.isNull(), false );
|
|
CHECK( firstPlanetNode.isElement(), true );
|
|
CHECK( firstPlanetNode.nextSibling().isNull(), false );
|
|
CHECK( firstPlanetNode.previousSibling().isNull(), true );
|
|
CHECK( firstPlanetNode.parentNode().isNull(), false );
|
|
CHECK( firstPlanetNode.parentNode()==rootElement, true );
|
|
CHECK( firstPlanetNode.parentNode()!=rootElement, false );
|
|
CHECK( firstPlanetNode.hasChildNodes(), false );
|
|
CHECK( firstPlanetNode.firstChild().isNull(), true );
|
|
CHECK( firstPlanetNode.lastChild().isNull(), true );
|
|
|
|
// element <mercurius>
|
|
KoXmlElement firstPlanetElement;
|
|
firstPlanetElement = firstPlanetNode.toElement();
|
|
CHECK( firstPlanetElement.isNull(), false );
|
|
CHECK( firstPlanetElement.isElement(), true );
|
|
CHECK( firstPlanetElement.parentNode().isNull(), false );
|
|
CHECK( firstPlanetElement.parentNode()==rootElement, true );
|
|
CHECK( firstPlanetElement.hasChildNodes(), false );
|
|
CHECK( firstPlanetElement.firstChild().isNull(), true );
|
|
CHECK( firstPlanetElement.lastChild().isNull(), true );
|
|
CHECK( firstPlanetElement.tagName(), QString("mercurius") );
|
|
CHECK( firstPlanetElement.prefix().isNull(), true );
|
|
|
|
// node <venus>
|
|
KoXmlNode secondPlanetNode;
|
|
secondPlanetNode = firstPlanetNode.nextSibling();
|
|
CHECK( secondPlanetNode.isNull(), false );
|
|
CHECK( secondPlanetNode.isElement(), true );
|
|
CHECK( secondPlanetNode.nextSibling().isNull(), false );
|
|
CHECK( secondPlanetNode.previousSibling().isNull(), false );
|
|
CHECK( secondPlanetNode.previousSibling()==firstPlanetNode, true );
|
|
CHECK( secondPlanetNode.previousSibling()==firstPlanetElement, true );
|
|
CHECK( secondPlanetNode.parentNode().isNull(), false );
|
|
CHECK( secondPlanetNode.parentNode()==rootElement, true );
|
|
CHECK( secondPlanetNode.parentNode()!=rootElement, false );
|
|
CHECK( secondPlanetNode.hasChildNodes(), false );
|
|
CHECK( secondPlanetNode.firstChild().isNull(), true );
|
|
CHECK( secondPlanetNode.lastChild().isNull(), true );
|
|
|
|
// element <venus>
|
|
KoXmlElement secondPlanetElement;
|
|
secondPlanetElement = secondPlanetNode.toElement();
|
|
CHECK( secondPlanetElement.isNull(), false );
|
|
CHECK( secondPlanetElement.isElement(), true );
|
|
CHECK( secondPlanetElement.nextSibling().isNull(), false );
|
|
CHECK( secondPlanetElement.previousSibling().isNull(), false );
|
|
CHECK( secondPlanetElement.previousSibling()==firstPlanetNode, true );
|
|
CHECK( secondPlanetElement.previousSibling()==firstPlanetElement, true );
|
|
CHECK( secondPlanetElement.parentNode().isNull(), false );
|
|
CHECK( secondPlanetElement.parentNode()==rootElement, true );
|
|
CHECK( secondPlanetElement.parentNode()!=rootElement, false );
|
|
CHECK( secondPlanetElement.hasChildNodes(), false );
|
|
CHECK( secondPlanetElement.firstChild().isNull(), true );
|
|
CHECK( secondPlanetElement.lastChild().isNull(), true );
|
|
CHECK( secondPlanetElement.tagName(), QString("venus") );
|
|
CHECK( secondPlanetElement.prefix().isNull(), true );
|
|
}
|
|
|
|
void testRootError()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
// multiple root nodes are not valid !
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<earth></earth><moon></moon>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), false );
|
|
CHECK( errorMsg.isEmpty(), false );
|
|
CHECK( errorMsg, QString("unexpected character") );
|
|
CHECK( errorLine, 1 );
|
|
CHECK( errorColumn, 17 );
|
|
}
|
|
|
|
void testMismatchedTag()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
xmlstream << "<earth></e>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), false );
|
|
CHECK( errorMsg.isEmpty(), false );
|
|
CHECK( errorMsg, QString("tag mismatch") );
|
|
CHECK( errorLine, 1 );
|
|
CHECK( errorColumn, 11 );
|
|
}
|
|
|
|
void testSimpleOpenDocumentText()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
|
|
// content.xml from a simple OpenDocument text
|
|
// it has only paragraph "Hello, world!"
|
|
// automatic styles, declarations and unnecessary namespaces are omitted.
|
|
xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
|
xmlstream << "<office:document-content ";
|
|
xmlstream << " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"";
|
|
xmlstream << " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"";
|
|
xmlstream << " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
|
|
xmlstream << " office:version=\"1.0\">";
|
|
xmlstream << " <office:automatic-styles/>";
|
|
xmlstream << " <office:body>";
|
|
xmlstream << " <office:text>";
|
|
xmlstream << " <text:p text:style-name=\"Standard\">Hello, world!</text:p>";
|
|
xmlstream << " </office:text>";
|
|
xmlstream << " </office:body>";
|
|
xmlstream << "</office:document-content>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
char* officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
|
|
char* textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
|
|
|
|
// <office:document-content>
|
|
KoXmlElement contentElement;
|
|
contentElement = doc.documentElement();
|
|
CHECK( contentElement.isNull(), false );
|
|
CHECK( contentElement.isElement(), true );
|
|
CHECK( contentElement.parentNode().isNull(), false );
|
|
CHECK( contentElement.parentNode().toDocument()==doc, true );
|
|
CHECK( contentElement.firstChild().isNull(), false );
|
|
CHECK( contentElement.lastChild().isNull(), false );
|
|
CHECK( contentElement.previousSibling().isNull(), false );
|
|
CHECK( contentElement.nextSibling().isNull(), true );
|
|
CHECK( contentElement.localName(), QString("document-content") );
|
|
CHECK( contentElement.hasAttributeNS(officeNS,"version"), true );
|
|
CHECK( contentElement.attributeNS(officeNS,"version",""), QString("1.0") );
|
|
|
|
// <office:automatic-styles>
|
|
KoXmlElement stylesElement;
|
|
stylesElement = KoXml::namedItemNS( contentElement, officeNS, "automatic-styles" );
|
|
CHECK( stylesElement.isNull(), false );
|
|
CHECK( stylesElement.isElement(), true );
|
|
CHECK( stylesElement.parentNode().isNull(), false );
|
|
CHECK( stylesElement.parentNode()==contentElement, true );
|
|
CHECK( stylesElement.firstChild().isNull(), true );
|
|
CHECK( stylesElement.lastChild().isNull(), true );
|
|
CHECK( stylesElement.previousSibling().isNull(), true );
|
|
CHECK( stylesElement.nextSibling().isNull(), false );
|
|
CHECK( stylesElement.localName(), QString("automatic-styles") );
|
|
|
|
// also same <office:automatic-styles>, but without namedItemNS
|
|
KoXmlNode styles2Element;
|
|
styles2Element = contentElement.firstChild().toElement();
|
|
CHECK( styles2Element.isNull(), false );
|
|
CHECK( styles2Element.isElement(), true );
|
|
CHECK( styles2Element.parentNode().isNull(), false );
|
|
CHECK( styles2Element.parentNode()==contentElement, true );
|
|
CHECK( styles2Element.firstChild().isNull(), true );
|
|
CHECK( styles2Element.lastChild().isNull(), true );
|
|
CHECK( styles2Element.previousSibling().isNull(), true );
|
|
CHECK( styles2Element.nextSibling().isNull(), false );
|
|
CHECK( styles2Element.localName(), QString("automatic-styles") );
|
|
|
|
// <office:body>
|
|
KoXmlElement bodyElement;
|
|
bodyElement = KoXml::namedItemNS( contentElement, officeNS, "body" );
|
|
CHECK( bodyElement.isNull(), false );
|
|
CHECK( bodyElement.isElement(), true );
|
|
CHECK( bodyElement.parentNode().isNull(), false );
|
|
CHECK( bodyElement.parentNode()==contentElement, true );
|
|
CHECK( bodyElement.firstChild().isNull(), false );
|
|
CHECK( bodyElement.lastChild().isNull(), false );
|
|
CHECK( bodyElement.previousSibling().isNull(), false );
|
|
CHECK( bodyElement.nextSibling().isNull(), true );
|
|
CHECK( bodyElement.localName(), QString("body") );
|
|
|
|
// also same <office:body>, but without namedItemNS
|
|
KoXmlElement body2Element;
|
|
body2Element = stylesElement.nextSibling().toElement();
|
|
CHECK( body2Element.isNull(), false );
|
|
CHECK( body2Element.isElement(), true );
|
|
CHECK( body2Element.parentNode().isNull(), false );
|
|
CHECK( body2Element.parentNode()==contentElement, true );
|
|
CHECK( body2Element.firstChild().isNull(), false );
|
|
CHECK( body2Element.lastChild().isNull(), false );
|
|
CHECK( body2Element.previousSibling().isNull(), false );
|
|
CHECK( body2Element.nextSibling().isNull(), true );
|
|
CHECK( body2Element.localName(), QString("body") );
|
|
|
|
// <office:text>
|
|
KoXmlElement textElement;
|
|
textElement = KoXml::namedItemNS( bodyElement, officeNS, "text" );
|
|
CHECK( textElement.isNull(), false );
|
|
CHECK( textElement.isElement(), true );
|
|
CHECK( textElement.parentNode().isNull(), false );
|
|
CHECK( textElement.parentNode()==bodyElement, true );
|
|
CHECK( textElement.firstChild().isNull(), false );
|
|
CHECK( textElement.lastChild().isNull(), false );
|
|
CHECK( textElement.previousSibling().isNull(), true );
|
|
CHECK( textElement.nextSibling().isNull(), true );
|
|
CHECK( textElement.localName(), QString("text") );
|
|
|
|
// the same <office:text>, but without namedItemNS
|
|
KoXmlElement text2Element;
|
|
text2Element = bodyElement.firstChild().toElement();
|
|
CHECK( text2Element.isNull(), false );
|
|
CHECK( text2Element.isElement(), true );
|
|
CHECK( text2Element.parentNode().isNull(), false );
|
|
CHECK( text2Element.parentNode()==bodyElement, true );
|
|
CHECK( text2Element.firstChild().isNull(), false );
|
|
CHECK( text2Element.lastChild().isNull(), false );
|
|
CHECK( text2Element.previousSibling().isNull(), true );
|
|
CHECK( text2Element.nextSibling().isNull(), true );
|
|
CHECK( text2Element.localName(), QString("text") );
|
|
|
|
// <text:p>
|
|
KoXmlElement parElement;
|
|
parElement = textElement.firstChild().toElement();
|
|
CHECK( parElement.isNull(), false );
|
|
CHECK( parElement.isElement(), true );
|
|
CHECK( parElement.parentNode().isNull(), false );
|
|
CHECK( parElement.parentNode()==textElement, true );
|
|
CHECK( parElement.firstChild().isNull(), false );
|
|
CHECK( parElement.lastChild().isNull(), false );
|
|
CHECK( parElement.previousSibling().isNull(), true );
|
|
CHECK( parElement.nextSibling().isNull(), true );
|
|
CHECK( parElement.tagName(), QString("p") );
|
|
CHECK( parElement.text(), QString("Hello, world!") );
|
|
CHECK( parElement.attributeNS( QString(textNS),"style-name",""), QString("Standard") );
|
|
}
|
|
|
|
void testSimpleOpenDocumentSpreadsheet()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
|
|
// content.xml from a simple OpenDocument spreadsheet
|
|
// the document has three worksheets, the last two are empty.
|
|
// on the first sheet, cell A1 contains the text "Hello, world".
|
|
// automatic styles, font declarations and unnecessary namespaces are omitted.
|
|
|
|
xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
|
xmlstream << "<office:document-content ";
|
|
xmlstream << "xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"";
|
|
xmlstream << "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
|
|
xmlstream << "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\">";
|
|
xmlstream << "<office:body>";
|
|
xmlstream << "<office:spreadsheet>";
|
|
xmlstream << "<table:table table:name=\"Sheet1\" table:style-name=\"ta1\" table:print=\"false\">";
|
|
xmlstream << "<table:table-column table:style-name=\"co1\" table:default-cell-style-name=\"Default\"/>";
|
|
xmlstream << "<table:table-row table:style-name=\"ro1\">";
|
|
xmlstream << "<table:table-cell office:value-type=\"string\">";
|
|
xmlstream << "<text:p>Hello, world</text:p>";
|
|
xmlstream << "</table:table-cell>";
|
|
xmlstream << "</table:table-row>";
|
|
xmlstream << "</table:table>";
|
|
xmlstream << "<table:table table:name=\"Sheet2\" table:style-name=\"ta1\" table:print=\"false\">";
|
|
xmlstream << "<table:table-column table:style-name=\"co1\" table:default-cell-style-name=\"Default\"/>";
|
|
xmlstream << "<table:table-row table:style-name=\"ro1\">";
|
|
xmlstream << "<table:table-cell/>";
|
|
xmlstream << "</table:table-row>";
|
|
xmlstream << "</table:table>";
|
|
xmlstream << "<table:table table:name=\"Sheet3\" table:style-name=\"ta1\" table:print=\"false\">";
|
|
xmlstream << "<table:table-column table:style-name=\"co1\" table:default-cell-style-name=\"Default\"/>";
|
|
xmlstream << "<table:table-row table:style-name=\"ro1\">";
|
|
xmlstream << "<table:table-cell/>";
|
|
xmlstream << "</table:table-row>";
|
|
xmlstream << "</table:table>";
|
|
xmlstream << "</office:spreadsheet>";
|
|
xmlstream << "</office:body>";
|
|
xmlstream << "</office:document-content>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
QString officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
|
|
QString tableNS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
|
|
QString textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
|
|
|
|
// <office:document-content>
|
|
KoXmlElement contentElement;
|
|
contentElement = doc.documentElement();
|
|
CHECK( contentElement.isNull(), false );
|
|
CHECK( contentElement.isElement(), true );
|
|
CHECK( contentElement.parentNode().isNull(), false );
|
|
CHECK( contentElement.parentNode().toDocument()==doc, true );
|
|
CHECK( contentElement.firstChild().isNull(), false );
|
|
CHECK( contentElement.lastChild().isNull(), false );
|
|
CHECK( contentElement.previousSibling().isNull(), false );
|
|
CHECK( contentElement.nextSibling().isNull(), true );
|
|
CHECK( contentElement.localName(), QString("document-content") );
|
|
|
|
// <office:body>
|
|
KoXmlElement bodyElement;
|
|
bodyElement = contentElement.firstChild().toElement();
|
|
CHECK( bodyElement.isNull(), false );
|
|
CHECK( bodyElement.isElement(), true );
|
|
CHECK( bodyElement.parentNode().isNull(), false );
|
|
CHECK( bodyElement.parentNode()==contentElement, true );
|
|
CHECK( bodyElement.firstChild().isNull(), false );
|
|
CHECK( bodyElement.lastChild().isNull(), false );
|
|
CHECK( bodyElement.previousSibling().isNull(), true );
|
|
CHECK( bodyElement.nextSibling().isNull(), true );
|
|
CHECK( bodyElement.localName(), QString("body") );
|
|
|
|
// <office:spreadsheet>
|
|
KoXmlElement spreadsheetElement;
|
|
spreadsheetElement = bodyElement.firstChild().toElement();
|
|
CHECK( spreadsheetElement.isNull(), false );
|
|
CHECK( spreadsheetElement.isElement(), true );
|
|
CHECK( spreadsheetElement.parentNode().isNull(), false );
|
|
CHECK( spreadsheetElement.parentNode()==bodyElement, true );
|
|
CHECK( spreadsheetElement.firstChild().isNull(), false );
|
|
CHECK( spreadsheetElement.lastChild().isNull(), false );
|
|
CHECK( spreadsheetElement.previousSibling().isNull(), true );
|
|
CHECK( spreadsheetElement.nextSibling().isNull(), true );
|
|
CHECK( spreadsheetElement.localName(), QString("spreadsheet") );
|
|
|
|
// <table:table> for Sheet1
|
|
KoXmlElement sheet1Element;
|
|
sheet1Element = spreadsheetElement.firstChild().toElement();
|
|
CHECK( sheet1Element.isNull(), false );
|
|
CHECK( sheet1Element.isElement(), true );
|
|
CHECK( sheet1Element.parentNode().isNull(), false );
|
|
CHECK( sheet1Element.parentNode()==spreadsheetElement, true );
|
|
CHECK( sheet1Element.firstChild().isNull(), false );
|
|
CHECK( sheet1Element.lastChild().isNull(), false );
|
|
CHECK( sheet1Element.previousSibling().isNull(), true );
|
|
CHECK( sheet1Element.nextSibling().isNull(), false );
|
|
CHECK( sheet1Element.tagName(), QString("table") );
|
|
CHECK( sheet1Element.hasAttributeNS(tableNS,"name"), true );
|
|
CHECK( sheet1Element.attributeNS(tableNS,"name",""), QString("Sheet1") );
|
|
CHECK( sheet1Element.attributeNS(tableNS,"style-name",""), QString("ta1") );
|
|
CHECK( sheet1Element.attributeNS(tableNS,"print",""), QString("false") );
|
|
|
|
KoXml::load( sheet1Element, 100 );
|
|
|
|
// <table:table-column>
|
|
KoXmlElement columnElement;
|
|
columnElement = sheet1Element.firstChild().toElement();
|
|
CHECK( columnElement.isNull(), false );
|
|
CHECK( columnElement.isElement(), true );
|
|
CHECK( columnElement.parentNode().isNull(), false );
|
|
CHECK( columnElement.parentNode()==sheet1Element, true );
|
|
CHECK( columnElement.firstChild().isNull(), true );
|
|
CHECK( columnElement.lastChild().isNull(), true );
|
|
CHECK( columnElement.previousSibling().isNull(), true );
|
|
CHECK( columnElement.nextSibling().isNull(), false );
|
|
CHECK( columnElement.tagName(), QString("table-column") );
|
|
CHECK( columnElement.attributeNS(tableNS,"style-name",""), QString("co1") );
|
|
CHECK( columnElement.attributeNS(tableNS,"default-cell-style-name",""), QString("Default") );
|
|
|
|
// <table:table-row>
|
|
KoXmlElement rowElement;
|
|
rowElement = columnElement.nextSibling().toElement();
|
|
CHECK( rowElement.isNull(), false );
|
|
CHECK( rowElement.isElement(), true );
|
|
CHECK( rowElement.parentNode().isNull(), false );
|
|
CHECK( rowElement.parentNode()==sheet1Element, true );
|
|
CHECK( rowElement.firstChild().isNull(), false );
|
|
CHECK( rowElement.lastChild().isNull(), false );
|
|
CHECK( rowElement.previousSibling().isNull(), false );
|
|
CHECK( rowElement.nextSibling().isNull(), true );
|
|
CHECK( rowElement.tagName(), QString("table-row") );
|
|
CHECK( rowElement.attributeNS(tableNS,"style-name",""), QString("ro1") );
|
|
|
|
// <table:table-cell>
|
|
KoXmlElement cellElement;
|
|
cellElement = rowElement.firstChild().toElement();
|
|
CHECK( cellElement.isNull(), false );
|
|
CHECK( cellElement.isElement(), true );
|
|
CHECK( cellElement.parentNode().isNull(), false );
|
|
CHECK( cellElement.parentNode()==rowElement, true );
|
|
CHECK( cellElement.firstChild().isNull(), false );
|
|
CHECK( cellElement.lastChild().isNull(), false );
|
|
CHECK( cellElement.previousSibling().isNull(), true );
|
|
CHECK( cellElement.nextSibling().isNull(), true );
|
|
CHECK( cellElement.tagName(), QString("table-cell") );
|
|
CHECK( cellElement.attributeNS(officeNS,"value-type",""), QString("string") );
|
|
|
|
// <text:p>
|
|
KoXmlElement parElement;
|
|
parElement = cellElement.firstChild().toElement();
|
|
CHECK( parElement.isNull(), false );
|
|
CHECK( parElement.isElement(), true );
|
|
CHECK( parElement.parentNode().isNull(), false );
|
|
CHECK( parElement.parentNode()==cellElement, true );
|
|
CHECK( parElement.firstChild().isNull(), false );
|
|
CHECK( parElement.lastChild().isNull(), false );
|
|
CHECK( parElement.previousSibling().isNull(), true );
|
|
CHECK( parElement.nextSibling().isNull(), true );
|
|
CHECK( parElement.tagName(), QString("p") );
|
|
CHECK( parElement.text(), QString("Hello, world") );
|
|
|
|
// <table:table> for Sheet2
|
|
KoXmlElement sheet2Element;
|
|
sheet2Element = sheet1Element.nextSibling().toElement();
|
|
CHECK( sheet2Element.isNull(), false );
|
|
CHECK( sheet2Element.isElement(), true );
|
|
CHECK( sheet2Element.parentNode().isNull(), false );
|
|
CHECK( sheet2Element.parentNode()==spreadsheetElement, true );
|
|
CHECK( sheet2Element.firstChild().isNull(), false );
|
|
CHECK( sheet2Element.lastChild().isNull(), false );
|
|
CHECK( sheet2Element.previousSibling().isNull(), false );
|
|
CHECK( sheet2Element.nextSibling().isNull(), false );
|
|
CHECK( sheet2Element.tagName(), QString("table") );
|
|
|
|
// </table:table> for Sheet3
|
|
KoXmlElement sheet3Element;
|
|
sheet3Element = sheet2Element.nextSibling().toElement();
|
|
CHECK( sheet3Element.isNull(), false );
|
|
CHECK( sheet3Element.isElement(), true );
|
|
CHECK( sheet3Element.parentNode().isNull(), false );
|
|
CHECK( sheet3Element.parentNode()==spreadsheetElement, true );
|
|
CHECK( sheet3Element.firstChild().isNull(), false );
|
|
CHECK( sheet3Element.lastChild().isNull(), false );
|
|
CHECK( sheet3Element.previousSibling().isNull(), false );
|
|
CHECK( sheet3Element.nextSibling().isNull(), true );
|
|
CHECK( sheet3Element.tagName(), QString("table") );
|
|
}
|
|
|
|
void testSimpleOpenDocumentPresentation()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
|
|
// content.xml from a simple OpenDocument presentation
|
|
// styles, declarations and unnecessary namespaces are omitted
|
|
// the first page is "Title" and has two text boxes
|
|
// the second page is
|
|
|
|
xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
|
xmlstream << "<office:document-content ";
|
|
xmlstream << " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" ";
|
|
xmlstream << " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
|
|
xmlstream << " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\" ";
|
|
xmlstream << " xmlns:presentation=\"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0\" ";
|
|
xmlstream << " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\" ";
|
|
xmlstream << " office:version=\"1.0\">";
|
|
xmlstream << " <office:scripts/>";
|
|
xmlstream << " <office:automatic-styles/>";
|
|
xmlstream << " <office:body>";
|
|
xmlstream << " <office:presentation>";
|
|
xmlstream << " <draw:page draw:name=\"Title\" draw:style-name=\"dp1\" ";
|
|
xmlstream << " draw:master-page-name=\"lyt-cool\" ";
|
|
xmlstream << " presentation:presentation-page-layout-name=\"AL1T0\">";
|
|
xmlstream << " <draw:frame presentation:style-name=\"pr1\" ";
|
|
xmlstream << " draw:text-style-name=\"P2\" draw:layer=\"layout\" ";
|
|
xmlstream << " svg:width=\"23.912cm\" svg:height=\"3.508cm\" ";
|
|
xmlstream << " svg:x=\"2.058cm\" svg:y=\"1.543cm\" ";
|
|
xmlstream << " presentation:class=\"title\" ";
|
|
xmlstream << " presentation:user-transformed=\"true\">";
|
|
xmlstream << " <draw:text-box>";
|
|
xmlstream << " <text:p text:style-name=\"P1\">Foobar</text:p>";
|
|
xmlstream << " </draw:text-box>";
|
|
xmlstream << " </draw:frame>";
|
|
xmlstream << " <draw:frame presentation:style-name=\"pr2\" ";
|
|
xmlstream << " draw:text-style-name=\"P3\" draw:layer=\"layout\"";
|
|
xmlstream << " svg:width=\"23.912cm\" svg:height=\"13.231cm\"";
|
|
xmlstream << " svg:x=\"2.058cm\" svg:y=\"5.838cm\" ";
|
|
xmlstream << " presentation:class=\"subtitle\">";
|
|
xmlstream << " <draw:text-box>";
|
|
xmlstream << " <text:p text:style-name=\"P3\">Foo</text:p>";
|
|
xmlstream << " </draw:text-box>";
|
|
xmlstream << " </draw:frame>";
|
|
xmlstream << " <presentation:notes draw:style-name=\"dp2\">";
|
|
xmlstream << " <draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"13.706cm\" svg:height=\"10.28cm\" svg:x=\"3.647cm\" svg:y=\"2.853cm\" draw:page-number=\"1\" presentation:class=\"page\"/>";
|
|
xmlstream << " <draw:frame presentation:style-name=\"pr3\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"14.518cm\" svg:height=\"11.411cm\" svg:x=\"3.249cm\" svg:y=\"14.13cm\" presentation:class=\"notes\" presentation:placeholder=\"true\">";
|
|
xmlstream << " <draw:text-box/>";
|
|
xmlstream << " </draw:frame>";
|
|
xmlstream << " </presentation:notes>";
|
|
xmlstream << " </draw:page>";
|
|
xmlstream << " <presentation:settings presentation:stay-on-top=\"true\"/>";
|
|
xmlstream << " </office:presentation>";
|
|
xmlstream << " </office:body>";
|
|
xmlstream << "</office:document-content>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
char* officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
|
|
char* drawNS = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";
|
|
char* textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
|
|
char* presentationNS = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";
|
|
char* svgNS = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";
|
|
|
|
// <office:document-content>
|
|
KoXmlElement contentElement;
|
|
contentElement = doc.documentElement();
|
|
CHECK( contentElement.isNull(), false );
|
|
|
|
CHECK( contentElement.isElement(), true );
|
|
CHECK( contentElement.parentNode().isNull(), false );
|
|
CHECK( contentElement.parentNode().toDocument()==doc, true );
|
|
CHECK( contentElement.firstChild().isNull(), false );
|
|
CHECK( contentElement.lastChild().isNull(), false );
|
|
CHECK( contentElement.previousSibling().isNull(), false );
|
|
|
|
CHECK( contentElement.nextSibling().isNull(), true );
|
|
CHECK( contentElement.localName(), QString("document-content") );
|
|
CHECK( contentElement.hasAttributeNS(officeNS,"version"), true );
|
|
CHECK( contentElement.attributeNS(officeNS,"version",""), QString("1.0") );
|
|
|
|
// <office:scripts>
|
|
KoXmlElement scriptsElement;
|
|
scriptsElement = KoXml::namedItemNS( contentElement, officeNS, "scripts" );
|
|
CHECK( scriptsElement.isNull(), false );
|
|
CHECK( scriptsElement.isElement(), true );
|
|
CHECK( scriptsElement.parentNode().isNull(), false );
|
|
CHECK( scriptsElement.parentNode()==contentElement, true );
|
|
CHECK( scriptsElement.firstChild().isNull(), true );
|
|
CHECK( scriptsElement.lastChild().isNull(), true );
|
|
CHECK( scriptsElement.previousSibling().isNull(), true );
|
|
CHECK( scriptsElement.nextSibling().isNull(), false );
|
|
CHECK( scriptsElement.localName(), QString("scripts") );
|
|
|
|
// <office:automatic-styles>
|
|
KoXmlElement stylesElement;
|
|
stylesElement = KoXml::namedItemNS( contentElement, officeNS, "automatic-styles" );
|
|
CHECK( stylesElement.isNull(), false );
|
|
CHECK( stylesElement.isElement(), true );
|
|
CHECK( stylesElement.parentNode().isNull(), false );
|
|
CHECK( stylesElement.parentNode()==contentElement, true );
|
|
CHECK( stylesElement.firstChild().isNull(), true );
|
|
CHECK( stylesElement.lastChild().isNull(), true );
|
|
CHECK( stylesElement.previousSibling().isNull(), false );
|
|
CHECK( stylesElement.nextSibling().isNull(), false );
|
|
CHECK( stylesElement.localName(), QString("automatic-styles") );
|
|
|
|
// also same <office:automatic-styles>, but without namedItemNS
|
|
KoXmlNode styles2Element;
|
|
styles2Element = scriptsElement.nextSibling().toElement();
|
|
CHECK( styles2Element.isNull(), false );
|
|
CHECK( styles2Element.isElement(), true );
|
|
CHECK( styles2Element.parentNode().isNull(), false );
|
|
CHECK( styles2Element.parentNode()==contentElement, true );
|
|
CHECK( styles2Element.firstChild().isNull(), true );
|
|
CHECK( styles2Element.lastChild().isNull(), true );
|
|
CHECK( styles2Element.previousSibling().isNull(), false );
|
|
CHECK( styles2Element.nextSibling().isNull(), false );
|
|
CHECK( styles2Element.localName(), QString("automatic-styles") );
|
|
|
|
// <office:body>
|
|
KoXmlElement bodyElement;
|
|
bodyElement = KoXml::namedItemNS( contentElement, officeNS, "body" );
|
|
CHECK( bodyElement.isNull(), false );
|
|
CHECK( bodyElement.isElement(), true );
|
|
CHECK( bodyElement.parentNode().isNull(), false );
|
|
CHECK( bodyElement.parentNode()==contentElement, true );
|
|
CHECK( bodyElement.firstChild().isNull(), false );
|
|
CHECK( bodyElement.lastChild().isNull(), false );
|
|
CHECK( bodyElement.previousSibling().isNull(), false );
|
|
CHECK( bodyElement.nextSibling().isNull(), true );
|
|
CHECK( bodyElement.localName(), QString("body") );
|
|
|
|
// also same <office:body>, but without namedItemNS
|
|
KoXmlElement body2Element;
|
|
body2Element = stylesElement.nextSibling().toElement();
|
|
CHECK( body2Element.isNull(), false );
|
|
CHECK( body2Element.isElement(), true );
|
|
CHECK( body2Element.parentNode().isNull(), false );
|
|
CHECK( body2Element.parentNode()==contentElement, true );
|
|
CHECK( body2Element.firstChild().isNull(), false );
|
|
CHECK( body2Element.lastChild().isNull(), false );
|
|
CHECK( body2Element.previousSibling().isNull(), false );
|
|
CHECK( body2Element.nextSibling().isNull(), true );
|
|
CHECK( body2Element.localName(), QString("body") );
|
|
|
|
// <office:presentation>
|
|
KoXmlElement presentationElement;
|
|
presentationElement = KoXml::namedItemNS( bodyElement, officeNS, "presentation" );
|
|
CHECK( presentationElement.isNull(), false );
|
|
CHECK( presentationElement.isElement(), true );
|
|
CHECK( presentationElement.parentNode().isNull(), false );
|
|
CHECK( presentationElement.parentNode()==bodyElement, true );
|
|
CHECK( presentationElement.firstChild().isNull(), false );
|
|
CHECK( presentationElement.lastChild().isNull(), false );
|
|
CHECK( presentationElement.previousSibling().isNull(), true );
|
|
CHECK( presentationElement.nextSibling().isNull(), true );
|
|
CHECK( presentationElement.localName(), QString("presentation") );
|
|
|
|
// the same <office:presentation>, but without namedItemNS
|
|
KoXmlElement presentation2Element;
|
|
presentation2Element = bodyElement.firstChild().toElement();
|
|
CHECK( presentation2Element.isNull(), false );
|
|
CHECK( presentation2Element.isElement(), true );
|
|
CHECK( presentation2Element.parentNode().isNull(), false );
|
|
CHECK( presentation2Element.parentNode()==bodyElement, true );
|
|
CHECK( presentation2Element.firstChild().isNull(), false );
|
|
CHECK( presentation2Element.lastChild().isNull(), false );
|
|
CHECK( presentation2Element.previousSibling().isNull(), true );
|
|
CHECK( presentation2Element.nextSibling().isNull(), true );
|
|
CHECK( presentation2Element.localName(), QString("presentation") );
|
|
|
|
// <draw:page> for "Title"
|
|
KoXmlElement titlePageElement;
|
|
titlePageElement = presentationElement.firstChild().toElement();
|
|
CHECK( titlePageElement.isNull(), false );
|
|
CHECK( titlePageElement.isElement(), true );
|
|
CHECK( titlePageElement.parentNode().isNull(), false );
|
|
CHECK( titlePageElement.parentNode()==presentationElement, true );
|
|
CHECK( titlePageElement.firstChild().isNull(), false );
|
|
CHECK( titlePageElement.lastChild().isNull(), false );
|
|
CHECK( titlePageElement.previousSibling().isNull(), true );
|
|
CHECK( titlePageElement.nextSibling().isNull(), false );
|
|
CHECK( titlePageElement.localName(), QString("page") );
|
|
CHECK( titlePageElement.attributeNS(drawNS,"name",""), QString("Title") );
|
|
CHECK( titlePageElement.attributeNS(drawNS,"style-name",""), QString("dp1") );
|
|
CHECK( titlePageElement.attributeNS(drawNS,"master-page-name",""), QString("lyt-cool") );
|
|
CHECK( titlePageElement.attributeNS(presentationNS,
|
|
"presentation-page-layout-name",""), QString("AL1T0") );
|
|
|
|
// <draw:frame> for the title frame
|
|
KoXmlElement titleFrameElement;
|
|
titleFrameElement = titlePageElement.firstChild().toElement();
|
|
CHECK( titleFrameElement.isNull(), false );
|
|
CHECK( titleFrameElement.isElement(), true );
|
|
CHECK( titleFrameElement.parentNode().isNull(), false );
|
|
CHECK( titleFrameElement.parentNode()==titlePageElement, true );
|
|
CHECK( titleFrameElement.firstChild().isNull(), false );
|
|
CHECK( titleFrameElement.lastChild().isNull(), false );
|
|
CHECK( titleFrameElement.previousSibling().isNull(), true );
|
|
CHECK( titleFrameElement.nextSibling().isNull(), false );
|
|
CHECK( titleFrameElement.localName(), QString("frame") );
|
|
CHECK( titleFrameElement.attributeNS(presentationNS,"style-name",""), QString("pr1") );
|
|
CHECK( titleFrameElement.attributeNS(presentationNS,"class",""), QString("title") );
|
|
CHECK( titleFrameElement.attributeNS(presentationNS,"user-transformed",""), QString("true") );
|
|
CHECK( titleFrameElement.attributeNS(drawNS,"text-style-name",""), QString("P2") );
|
|
CHECK( titleFrameElement.attributeNS(drawNS,"layer",""), QString("layout") );
|
|
CHECK( titleFrameElement.attributeNS(svgNS,"width",""), QString("23.912cm") );
|
|
CHECK( titleFrameElement.attributeNS(svgNS,"height",""), QString("3.508cm") );
|
|
CHECK( titleFrameElement.attributeNS(svgNS,"x",""), QString("2.058cm") );
|
|
CHECK( titleFrameElement.attributeNS(svgNS,"y",""), QString("1.543cm") );
|
|
|
|
// <draw:text-box> of the title frame
|
|
KoXmlElement titleBoxElement;
|
|
titleBoxElement = titleFrameElement.firstChild().toElement();
|
|
CHECK( titleBoxElement.isNull(), false );
|
|
CHECK( titleBoxElement.isElement(), true );
|
|
CHECK( titleBoxElement.parentNode().isNull(), false );
|
|
CHECK( titleBoxElement.parentNode()==titleFrameElement, true );
|
|
CHECK( titleBoxElement.firstChild().isNull(), false );
|
|
CHECK( titleBoxElement.lastChild().isNull(), false );
|
|
CHECK( titleBoxElement.previousSibling().isNull(), true );
|
|
CHECK( titleBoxElement.nextSibling().isNull(), true );
|
|
CHECK( titleBoxElement.localName(), QString("text-box") );
|
|
|
|
// <text:p> for the title text-box
|
|
KoXmlElement titleParElement;
|
|
titleParElement = titleBoxElement.firstChild().toElement();
|
|
CHECK( titleParElement.isNull(), false );
|
|
CHECK( titleParElement.isElement(), true );
|
|
CHECK( titleParElement.parentNode().isNull(), false );
|
|
CHECK( titleParElement.parentNode()==titleBoxElement, true );
|
|
CHECK( titleParElement.firstChild().isNull(), false );
|
|
CHECK( titleParElement.lastChild().isNull(), false );
|
|
CHECK( titleParElement.previousSibling().isNull(), true );
|
|
CHECK( titleParElement.nextSibling().isNull(), true );
|
|
CHECK( titleParElement.localName(), QString("p") );
|
|
CHECK( titleParElement.attributeNS(textNS,"style-name",""), QString("P1") );
|
|
CHECK( titleParElement.text(), QString("Foobar") );
|
|
|
|
// <draw:frame> for the subtitle frame
|
|
KoXmlElement subtitleFrameElement;
|
|
subtitleFrameElement = titleFrameElement.nextSibling().toElement();
|
|
CHECK( subtitleFrameElement.isNull(), false );
|
|
CHECK( subtitleFrameElement.isElement(), true );
|
|
CHECK( subtitleFrameElement.parentNode().isNull(), false );
|
|
CHECK( subtitleFrameElement.parentNode()==titlePageElement, true );
|
|
CHECK( subtitleFrameElement.firstChild().isNull(), false );
|
|
CHECK( subtitleFrameElement.lastChild().isNull(), false );
|
|
CHECK( subtitleFrameElement.previousSibling().isNull(), false );
|
|
CHECK( subtitleFrameElement.nextSibling().isNull(), false );
|
|
CHECK( subtitleFrameElement.localName(), QString("frame") );
|
|
CHECK( subtitleFrameElement.attributeNS(presentationNS,"style-name",""), QString("pr2") );
|
|
CHECK( subtitleFrameElement.attributeNS(presentationNS,"class",""), QString("subtitle") );
|
|
CHECK( subtitleFrameElement.hasAttributeNS(presentationNS,"user-transformed"), false );
|
|
CHECK( subtitleFrameElement.attributeNS(drawNS,"text-style-name",""), QString("P3") );
|
|
CHECK( subtitleFrameElement.attributeNS(drawNS,"layer",""), QString("layout") );
|
|
CHECK( subtitleFrameElement.attributeNS(svgNS,"width",""), QString("23.912cm") );
|
|
CHECK( subtitleFrameElement.attributeNS(svgNS,"height",""), QString("13.231cm") );
|
|
CHECK( subtitleFrameElement.attributeNS(svgNS,"x",""), QString("2.058cm") );
|
|
CHECK( subtitleFrameElement.attributeNS(svgNS,"y",""), QString("5.838cm") );
|
|
|
|
// <draw:text-box> of the subtitle frame
|
|
KoXmlElement subtitleBoxElement;
|
|
subtitleBoxElement = subtitleFrameElement.firstChild().toElement();
|
|
CHECK( subtitleBoxElement.isNull(), false );
|
|
CHECK( subtitleBoxElement.isElement(), true );
|
|
CHECK( subtitleBoxElement.parentNode().isNull(), false );
|
|
CHECK( subtitleBoxElement.parentNode()==subtitleFrameElement, true );
|
|
CHECK( subtitleBoxElement.firstChild().isNull(), false );
|
|
CHECK( subtitleBoxElement.lastChild().isNull(), false );
|
|
CHECK( subtitleBoxElement.previousSibling().isNull(), true );
|
|
CHECK( subtitleBoxElement.nextSibling().isNull(), true );
|
|
CHECK( subtitleBoxElement.localName(), QString("text-box") );
|
|
|
|
// <text:p> for the subtitle text-box
|
|
KoXmlElement subtitleParElement;
|
|
subtitleParElement = subtitleBoxElement.firstChild().toElement();
|
|
CHECK( subtitleParElement.isNull(), false );
|
|
CHECK( subtitleParElement.isElement(), true );
|
|
CHECK( subtitleParElement.parentNode().isNull(), false );
|
|
CHECK( subtitleParElement.parentNode()==subtitleBoxElement, true );
|
|
CHECK( subtitleParElement.firstChild().isNull(), false );
|
|
CHECK( subtitleParElement.lastChild().isNull(), false );
|
|
CHECK( subtitleParElement.previousSibling().isNull(), true );
|
|
CHECK( subtitleParElement.nextSibling().isNull(), true );
|
|
CHECK( subtitleParElement.localName(), QString("p") );
|
|
CHECK( subtitleParElement.attributeNS(textNS,"style-name",""), QString("P3") );
|
|
CHECK( subtitleParElement.text(), QString("Foo") );
|
|
}
|
|
|
|
void testSimpleOpenDocumentFormula()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
|
|
// content.xml from a simple OpenDocument formula
|
|
// this is essentially MathML
|
|
xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
|
xmlstream << "<!DOCTYPE math:math PUBLIC \"-//OpenOffice.org//DTD Modified W3C MathML 1.01//EN\" \"math.dtd\">";
|
|
xmlstream << "<math:math xmlns:math=\"http://www.w3.org/1998/Math/MathML\">";
|
|
xmlstream << " <math:semantics>";
|
|
xmlstream << " <math:mrow>";
|
|
xmlstream << " <math:mi>E</math:mi>";
|
|
xmlstream << " <math:mo math:stretchy=\"false\">=</math:mo>";
|
|
xmlstream << " <math:msup>";
|
|
xmlstream << " <math:mi math:fontstyle=\"italic\">mc</math:mi>";
|
|
xmlstream << " <math:mn>2</math:mn>";
|
|
xmlstream << " </math:msup>";
|
|
xmlstream << " </math:mrow>";
|
|
xmlstream << " <math:annotation math:encoding=\"StarMath 5.0\">E = mc^2 </math:annotation>";
|
|
xmlstream << " </math:semantics>";
|
|
xmlstream << "</math:math>";
|
|
|
|
KoXmlDocument doc;
|
|
CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
char* mathNS = "http://www.w3.org/1998/Math/MathML";
|
|
|
|
// <math:math>
|
|
KoXmlElement mathElement;
|
|
mathElement = doc.documentElement();
|
|
CHECK( mathElement.isNull(), false );
|
|
CHECK( mathElement.isElement(), true );
|
|
CHECK( mathElement.parentNode().isNull(), false );
|
|
CHECK( mathElement.parentNode().toDocument()==doc, true );
|
|
CHECK( mathElement.firstChild().isNull(), false );
|
|
CHECK( mathElement.lastChild().isNull(), false );
|
|
CHECK( mathElement.previousSibling().isNull(), false );
|
|
CHECK( mathElement.nextSibling().isNull(), true );
|
|
CHECK( mathElement.localName(), QString("math") );
|
|
|
|
// <math:semantics>
|
|
KoXmlElement semanticsElement;
|
|
semanticsElement = KoXml::namedItemNS( mathElement, mathNS, "semantics" );
|
|
CHECK( semanticsElement.isNull(), false );
|
|
CHECK( semanticsElement.isElement(), true );
|
|
CHECK( semanticsElement.parentNode().isNull(), false );
|
|
CHECK( semanticsElement.parentNode().toElement()==mathElement, true );
|
|
CHECK( semanticsElement.firstChild().isNull(), false );
|
|
CHECK( semanticsElement.lastChild().isNull(), false );
|
|
CHECK( semanticsElement.previousSibling().isNull(), true );
|
|
CHECK( semanticsElement.nextSibling().isNull(), true );
|
|
CHECK( semanticsElement.localName(), QString("semantics") );
|
|
|
|
// the same <math:semantics> but without namedItemNS
|
|
KoXmlElement semantics2Element;
|
|
semantics2Element = mathElement.firstChild().toElement();
|
|
CHECK( semantics2Element.isNull(), false );
|
|
CHECK( semantics2Element.isElement(), true );
|
|
CHECK( semantics2Element.parentNode().isNull(), false );
|
|
CHECK( semantics2Element.parentNode().toElement()==mathElement, true );
|
|
CHECK( semantics2Element.firstChild().isNull(), false );
|
|
CHECK( semantics2Element.lastChild().isNull(), false );
|
|
CHECK( semantics2Element.previousSibling().isNull(), true );
|
|
CHECK( semantics2Element.nextSibling().isNull(), true );
|
|
CHECK( semantics2Element.localName(), QString("semantics") );
|
|
|
|
// <math:mrow>
|
|
KoXmlElement mrowElement;
|
|
mrowElement = semanticsElement.firstChild().toElement();
|
|
CHECK( mrowElement.isNull(), false );
|
|
CHECK( mrowElement.isElement(), true );
|
|
CHECK( mrowElement.parentNode().isNull(), false );
|
|
CHECK( mrowElement.parentNode().toElement()==semanticsElement, true );
|
|
CHECK( mrowElement.firstChild().isNull(), false );
|
|
CHECK( mrowElement.lastChild().isNull(), false );
|
|
CHECK( mrowElement.previousSibling().isNull(), true );
|
|
CHECK( mrowElement.nextSibling().isNull(), false );
|
|
CHECK( mrowElement.localName(), QString("mrow") );
|
|
|
|
// <math:mi> for "E"
|
|
KoXmlElement miElement;
|
|
miElement = mrowElement.firstChild().toElement();
|
|
CHECK( miElement.isNull(), false );
|
|
CHECK( miElement.isElement(), true );
|
|
CHECK( miElement.parentNode().isNull(), false );
|
|
CHECK( miElement.parentNode().toElement()==mrowElement, true );
|
|
CHECK( miElement.firstChild().isNull(), false );
|
|
CHECK( miElement.lastChild().isNull(), false );
|
|
CHECK( miElement.previousSibling().isNull(), true );
|
|
CHECK( miElement.nextSibling().isNull(), false );
|
|
CHECK( miElement.localName(), QString("mi") );
|
|
|
|
// <math:mo> for "="
|
|
KoXmlElement moElement;
|
|
moElement = miElement.nextSibling().toElement();
|
|
CHECK( moElement.isNull(), false );
|
|
CHECK( moElement.isElement(), true );
|
|
CHECK( moElement.parentNode().isNull(), false );
|
|
CHECK( moElement.parentNode().toElement()==mrowElement, true );
|
|
CHECK( moElement.firstChild().isNull(), false );
|
|
CHECK( moElement.lastChild().isNull(), false );
|
|
CHECK( moElement.previousSibling().isNull(), false );
|
|
CHECK( moElement.nextSibling().isNull(), false );
|
|
CHECK( moElement.localName(), QString("mo") );
|
|
CHECK( moElement.attributeNS(mathNS,"stretchy",""), QString("false") );
|
|
|
|
// <math:msup> for "mc" and superscripted "2"
|
|
KoXmlElement msupElement;
|
|
msupElement = moElement.nextSibling().toElement();
|
|
CHECK( msupElement.isNull(), false );
|
|
CHECK( msupElement.isElement(), true );
|
|
CHECK( msupElement.parentNode().isNull(), false );
|
|
CHECK( msupElement.parentNode().toElement()==mrowElement, true );
|
|
CHECK( msupElement.firstChild().isNull(), false );
|
|
CHECK( msupElement.lastChild().isNull(), false );
|
|
CHECK( msupElement.previousSibling().isNull(), false );
|
|
CHECK( msupElement.nextSibling().isNull(), true );
|
|
CHECK( msupElement.localName(), QString("msup") );
|
|
|
|
// <math:mi> inside the <math:msup> for "mc"
|
|
KoXmlElement mcElement;
|
|
mcElement = msupElement.firstChild().toElement();
|
|
CHECK( mcElement.isNull(), false );
|
|
CHECK( mcElement.isElement(), true );
|
|
CHECK( mcElement.parentNode().isNull(), false );
|
|
CHECK( mcElement.parentNode().toElement()==msupElement, true );
|
|
CHECK( mcElement.firstChild().isNull(), false );
|
|
CHECK( mcElement.lastChild().isNull(), false );
|
|
CHECK( mcElement.previousSibling().isNull(), true );
|
|
CHECK( mcElement.nextSibling().isNull(), false );
|
|
CHECK( mcElement.localName(), QString("mi") );
|
|
CHECK( mcElement.text(), QString("mc") );
|
|
CHECK( mcElement.attributeNS(mathNS,"fontstyle",""), QString("italic") );
|
|
|
|
// <math:mn> inside the <math:msup> for "2" (superscript)
|
|
KoXmlElement mnElement;
|
|
mnElement = mcElement.nextSibling().toElement();
|
|
CHECK( mnElement.isNull(), false );
|
|
CHECK( mnElement.isElement(), true );
|
|
CHECK( mnElement.parentNode().isNull(), false );
|
|
CHECK( mnElement.parentNode().toElement()==msupElement, true );
|
|
CHECK( mnElement.firstChild().isNull(), false );
|
|
CHECK( mnElement.lastChild().isNull(), false );
|
|
CHECK( mnElement.previousSibling().isNull(), false );
|
|
CHECK( mnElement.nextSibling().isNull(), true );
|
|
CHECK( mnElement.localName(), QString("mn") );
|
|
CHECK( mnElement.text(), QString("2") );
|
|
|
|
// <math:annotation>
|
|
KoXmlElement annotationElement;
|
|
annotationElement = semanticsElement.lastChild().toElement();
|
|
CHECK( annotationElement.isNull(), false );
|
|
CHECK( annotationElement.isElement(), true );
|
|
CHECK( annotationElement.parentNode().isNull(), false );
|
|
CHECK( annotationElement.parentNode().toElement()==semanticsElement, true );
|
|
CHECK( annotationElement.firstChild().isNull(), false );
|
|
CHECK( annotationElement.lastChild().isNull(), false );
|
|
CHECK( annotationElement.previousSibling().isNull(), false );
|
|
CHECK( annotationElement.nextSibling().isNull(), true );
|
|
CHECK( annotationElement.localName(), QString("annotation") );
|
|
CHECK( annotationElement.text(), QString("E = mc^2 ") );
|
|
CHECK( annotationElement.attributeNS(mathNS,"encoding",""), QString("StarMath 5.0") );
|
|
}
|
|
|
|
void testLargeOpenDocumentSpreadsheet()
|
|
{
|
|
QString errorMsg;
|
|
int errorLine = 0;
|
|
int errorColumn = 0;
|
|
|
|
int sheetCount = 4;
|
|
int rowCount = 200;
|
|
int colCount = 200*2;
|
|
|
|
QByteArray xmlbuf;
|
|
QBuffer xmldevice( xmlbuf );
|
|
QTextStream xmlstream( xmlbuf, IO_WriteOnly );
|
|
|
|
// content.xml
|
|
xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
|
xmlstream << "<office:document-content ";
|
|
xmlstream << "xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" ";
|
|
xmlstream << "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
|
|
xmlstream << "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\" >";
|
|
xmlstream << "<office:body>";
|
|
xmlstream << "<office:spreadsheet>";
|
|
for( int i = 0; i < sheetCount; i++ )
|
|
{
|
|
QString sheetName = QString("Sheet%1").arg(i+1);
|
|
xmlstream << "<table:table table:name=\"" << sheetName;
|
|
xmlstream << "\" table:print=\"false\">";
|
|
for( int j = 0; j < rowCount; j++ )
|
|
{
|
|
xmlstream << "<table:table-row>";
|
|
for( int k = 0; k < colCount; k++ )
|
|
{
|
|
xmlstream << "<table:table-cell office:value-type=\"string\">";
|
|
xmlstream << "<text:p>Hello, world</text:p>";
|
|
xmlstream << "</table:table-cell>";
|
|
}
|
|
xmlstream << "</table:table-row>";
|
|
}
|
|
xmlstream << "</table:table>";
|
|
}
|
|
xmlstream << "</office:spreadsheet>";
|
|
xmlstream << "</office:body>";
|
|
xmlstream << "</office:document-content>";
|
|
|
|
printf("Raw XML size: %d KB\n", xmlbuf.size()/1024 );
|
|
|
|
QTime timer;
|
|
timer.start();
|
|
|
|
#if 1
|
|
// just to test parsing speed with plain dumb handler
|
|
QXmlSimpleReader* reader = new QXmlSimpleReader;
|
|
reader->setFeature( "http://xml.org/sax/features/namespaces", true );
|
|
QXmlDefaultHandler handler;
|
|
reader->setContentHandler( &handler );
|
|
reader->setErrorHandler( &handler );
|
|
reader->setLexicalHandler( &handler );
|
|
reader->setDeclHandler( &handler );
|
|
reader->setDTDHandler( &handler );
|
|
QXmlInputSource xmlSource;
|
|
xmlSource.setData( QString::fromUtf8( xmlbuf.data(), xmlbuf.size() ) );
|
|
timer.start();
|
|
reader->parse( &xmlSource );
|
|
printf("Large spreadsheet: QXmlDefaultHandler parsing time is %d ms\n", timer.elapsed() );
|
|
delete reader;
|
|
#endif
|
|
|
|
timer.start();
|
|
KoXmlDocument doc;
|
|
|
|
// uncomment to see the performance if on-demand/lazy loading is not used
|
|
// will definitely eat more memory
|
|
#ifndef KOXML_USE_QDOM
|
|
doc.setFastLoading( true );
|
|
#endif
|
|
|
|
CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
|
|
CHECK( errorMsg.isEmpty(), true );
|
|
CHECK( errorLine, 0 );
|
|
CHECK( errorColumn, 0 );
|
|
|
|
printf("Large spreadsheet: parsing time is %d ms\n", timer.elapsed() );
|
|
|
|
// release memory taken by the XML document content
|
|
xmlbuf.resize( 0 );
|
|
|
|
// namespaces that will be used
|
|
QString officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
|
|
QString tableNS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
|
|
QString textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
|
|
|
|
// <office:document-content>
|
|
KoXmlElement contentElement;
|
|
contentElement = doc.documentElement();
|
|
CHECK( contentElement.isNull(), false );
|
|
CHECK( contentElement.isElement(), true );
|
|
CHECK( contentElement.localName(), QString("document-content") );
|
|
|
|
// <office:body>
|
|
KoXmlElement bodyElement;
|
|
bodyElement = contentElement.firstChild().toElement();
|
|
CHECK( bodyElement.isNull(), false );
|
|
CHECK( bodyElement.isElement(), true );
|
|
CHECK( bodyElement.localName(), QString("body") );
|
|
|
|
// <office:spreadsheet>
|
|
KoXmlElement spreadsheetElement;
|
|
spreadsheetElement = bodyElement.firstChild().toElement();
|
|
CHECK( spreadsheetElement.isNull(), false );
|
|
CHECK( spreadsheetElement.isElement(), true );
|
|
CHECK( spreadsheetElement.localName(), QString("spreadsheet") );
|
|
|
|
// now we visit every sheet, every row, every cell
|
|
timer.start();
|
|
KoXmlElement tableElement;
|
|
tableElement = spreadsheetElement.firstChild().toElement();
|
|
for( int table=0; table < sheetCount; table++ )
|
|
{
|
|
QString tableName = QString("Sheet%1").arg(table+1);
|
|
CHECK( tableElement.isNull(), false );
|
|
CHECK( tableElement.isElement(), true );
|
|
CHECK( tableElement.localName(), QString("table") );
|
|
CHECK( tableElement.hasAttributeNS(tableNS,"name"), true );
|
|
CHECK( tableElement.attributeNS(tableNS,"name",""), tableName );
|
|
CHECK( tableElement.attributeNS(tableNS,"print",""), QString("false") );
|
|
|
|
// load everything for this table
|
|
KoXml::load( tableElement, 99 );
|
|
|
|
CHECK( tableElement.parentNode().isNull(), false );
|
|
CHECK( tableElement.parentNode()==spreadsheetElement, true );
|
|
CHECK( tableElement.firstChild().isNull(), false );
|
|
CHECK( tableElement.lastChild().isNull(), false );
|
|
|
|
KoXmlElement rowElement;
|
|
rowElement = tableElement.firstChild().toElement();
|
|
for( int row=0; row < rowCount; row++ )
|
|
{
|
|
CHECK( rowElement.isNull(), false );
|
|
CHECK( rowElement.isElement(), true );
|
|
CHECK( rowElement.localName(), QString("table-row") );
|
|
CHECK( rowElement.parentNode().isNull(), false );
|
|
CHECK( rowElement.parentNode()==tableElement, true );
|
|
CHECK( rowElement.firstChild().isNull(), false );
|
|
CHECK( rowElement.lastChild().isNull(), false );
|
|
|
|
KoXmlElement cellElement;
|
|
cellElement = rowElement.firstChild().toElement();
|
|
for( int col=0; col < colCount; col++ )
|
|
{
|
|
CHECK( cellElement.isNull(), false );
|
|
CHECK( cellElement.isElement(), true );
|
|
CHECK( cellElement.localName(), QString("table-cell") );
|
|
CHECK( cellElement.text(), QString("Hello, world") );
|
|
CHECK( cellElement.hasAttributeNS(officeNS,"value-type"), true );
|
|
CHECK( cellElement.attributeNS(officeNS,"value-type",""), QString("string" ) );
|
|
CHECK( cellElement.parentNode().isNull(), false );
|
|
CHECK( cellElement.parentNode()==rowElement, true );
|
|
CHECK( cellElement.firstChild().isNull(), false );
|
|
CHECK( cellElement.lastChild().isNull(), false );
|
|
cellElement = cellElement.nextSibling().toElement();
|
|
}
|
|
|
|
//KoXml::unload( rowElement );
|
|
rowElement = rowElement.nextSibling().toElement();
|
|
}
|
|
|
|
KoXml::unload( tableElement );
|
|
tableElement = tableElement.nextSibling().toElement();
|
|
}
|
|
|
|
printf("Large spreadsheet: iterating time is %d ms\n", timer.elapsed() );
|
|
}
|
|
|
|
int main( int argc, char** argv )
|
|
{
|
|
Q_UNUSED( argc );
|
|
Q_UNUSED( argv );
|
|
|
|
testNode();
|
|
testElement();
|
|
testAttributes();
|
|
testText();
|
|
testCDATA();
|
|
testDocument();
|
|
testNamespace();
|
|
|
|
testUnload();
|
|
|
|
testSimpleXML();
|
|
testRootError();
|
|
testMismatchedTag();
|
|
|
|
testSimpleOpenDocumentText();
|
|
testSimpleOpenDocumentSpreadsheet();
|
|
testSimpleOpenDocumentPresentation();
|
|
testSimpleOpenDocumentFormula();
|
|
|
|
// testLargeOpenDocumentSpreadsheet();
|
|
|
|
#ifdef KOXML_USE_QDOM
|
|
printf("Using QDom: ");
|
|
#else
|
|
printf("Using KoXml: ");
|
|
#endif
|
|
printf("%d tests, %d failed\n", testCount, testFailed );
|
|
|
|
return testFailed;
|
|
}
|