Hi Vishesh,
thanks a lot for the patch.
I would gladly include it in Soprano but there is one problem:
sopranocmd already has N3 parsing which is a bit more complex than your
version. It for example also includes prefix expansion. I already
started on a patch to convert that into a method of Node. The problem is
that I am not sure about the API yet.
Would you be interested to compare our patches? Maybe you have a good
idea on how to solve the problems I am facing: I am not too happy about
the error pointer parameter and the way the prefixes can be specified. I
already thought of maybe even creating a NodeParser class but then again
that seems a bit over the top...
Cheers,
Sebastian
On 03/24/2010 09:08 PM, Vishesh Handa wrote:
> Hi
>
> I created a new function *static Node createFromN3( const QString& n3
> )*. It creates a Soprano::Node from an N3 String. I've /tried /to
> document it in the header file, but I'm not too sure if it's correct
> (the documentation). It would be nice if somebody could go through it,
> please.
>
> The Patch had a base directory of /kdesupport/soprano/soprano/
> /
> - Vishesh Handa
>
>
>
> _______________________________________________
> Nepomuk mailing list
> [email protected]
> https://mail.kde.org/mailman/listinfo/nepomuk
Index: node.h
===================================================================
--- node.h (revision 1101894)
+++ node.h (working copy)
@@ -26,6 +26,8 @@
#include <QtCore/QUrl>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QTextStream>
+#include <QtCore/QHash>
+#include <QtCore/QString>
#include "soprano_export.h"
#include "literalvalue.h"
@@ -34,6 +36,10 @@
namespace Soprano
{
+ namespace Error {
+ class Error;
+ }
+
/**
* \class Node node.h Soprano/Node
*
@@ -429,12 +435,31 @@
* "09-08-1977T17:42.234Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>
* \endcode
*
- * \sa toN3
+ * \sa toN3(), fromN3()
*
* \since 2.3
*/
static QString literalToN3( const LiteralValue& literal );
+ /**
+ * Convert a node from its N3 representation.
+ *
+ * \param n3 The N3 representation of the node. \p true and \p false
are treated as boolean
+ * literals, any string that can be parsed into a number is treated as
integer or double
+ * literal, while any other string that is not a resource, blank node,
or typed literal
+ * is treated as a plain literal.
+ * \param bnames An optional map of namespace abbreviations that could
be used in \p n3.
+ * \param error An optional Error which will be filled in case parsing
\p b3 fails.
+ *
+ * \return A %Node representing the parsed version of \p n3 or an
invalid %Node in case
+ * parsing failed. In the latter case \p error will be filled with
parsing error details.
+ *
+ * \sa resourceToN3(), literalToN3(), blankToN3(), toN3()
+ *
+ * \since 2.4
+ */
+ static Node fromN3( const QString& n3, /*const QHash<QString, QUrl>&
bnames = QHash<QString, QUrl>(), */Error::Error* error = 0 );
+
private:
class NodeData;
class ResourceNodeData;
Index: node.cpp
===================================================================
--- node.cpp (revision 1101894)
+++ node.cpp (working copy)
@@ -21,10 +21,14 @@
*/
#include "node.h"
+#include "error.h"
+#include "locator.h"
+#include "vocabulary/rdf.h"
#include <QtCore/QString>
#include <QtCore/QUrl>
#include <QtCore/QDebug>
+#include <QtCore/QRegExp>
@@ -425,6 +439,102 @@
}
+namespace {
+ // FIXME: use QRegExp for all parsing.
+ // FIXME: Create a private NodeParser class which can also find the end of
an n3 encoded node so we can reuse it
+ // in the NQuadParser.
+ QRegExp s_prefixedUriRx( "(\\w+)\\:(\\w+)" );
+// QRegExp s_typedLiteral1Rx( "^\"\"\"[^\"]+\"\"\"\\^\\^.+$" );
+// QRegExp s_typedLiteral2Rx( "^\"[^\"]+\"\\^\\^.+$" );
+
+ QUrl parseUri( const QString& s ) {
+ // try to be a little smart about user input
+ if ( s.contains( '%' ) ) {
+ QByteArray b = s.toAscii();
+ if ( !b.isEmpty() ) {
+ return QUrl::fromEncoded( b );
+ }
+ }
+ return QUrl( s );
+ }
+}
+
+// static
+Soprano::Node Soprano::Node::fromN3( const QString& s, /*const QHash<QString,
QUrl>& bnames, */Error::Error* error )
+{
+ // FIXME: put this in the parameters or for advanced users in a dedicated
NodeParser class
+ QHash<QString, QUrl> bnames;
+
+ if ( s.isEmpty() ) {
+ return Soprano::Node();
+ }
+ else if ( s[0] == '<' && s[s.length()-1] == '>' ) {
+ return Soprano::Node( parseUri( s.mid( 1, s.length()-2 ) ) );
+ }
+ else if ( s[0] == '_' && s.length() > 2 && s[1] == ':' ) {
+ return Soprano::Node::createBlankNode( s.mid( 2 ) );
+ }
+ // FIXME: also handle """ as delimiters
+ else if ( s[0] == '"' ) {
+ QString value = s;
+ QString literalType;
+ int pos = s.indexOf( "\"^^<" );
+ if ( pos > 0 ) {
+ literalType = s.mid( pos + 4, s.length() - pos - 5 );
+ value = s.mid( 1, pos-1 );
+ return Soprano::LiteralValue::fromString( value, QUrl( literalType
) );
+ }
+ else {
+ QString lang;
+ pos = s.indexOf( "\"@" );
+ int len = s.length()-2;
+ if ( pos > 0 ) {
+ lang = s.mid( pos+2, s.length() - pos - 2 );
+ len -= lang.length() + 1;
+ }
+ value = s.mid( 1, len );
+ return Soprano::LiteralValue::createPlainLiteral( value, lang );
+ }
+ }
+ else if ( s_prefixedUriRx.exactMatch( s ) ) {
+ const QString bname = s_prefixedUriRx.cap( 1 );
+ QUrl ns = bnames[bname];
+ if ( ns.isValid() ) {
+ return QUrl( ns.toString() + s_prefixedUriRx.cap( 2 ) );
+ }
+ else {
+ if( error ) {
+ *error = Error::ParserError( Error::Locator( 0, 0 ),
QString::fromLatin1("Unknown namespace '%1'.").arg(bname) );
+ }
+ return Soprano::Node();
+ }
+ }
+ else if ( s == QLatin1String( "a" ) ) {
+ return Soprano::Vocabulary::RDF::type();
+ }
+ else {
+ // we only check for boolean, integer and double here
+ if ( s.toLower() == "false" )
+ return Soprano::LiteralValue( false );
+ else if ( s.toLower() == "true" )
+ return Soprano::LiteralValue( true );
+
+ bool ok = false;
+ int val = s.toInt( &ok );
+ if ( ok ) {
+ return Soprano::LiteralValue( val );
+ }
+ double dVal = s.toDouble( &ok );
+ if ( ok ) {
+ return Soprano::LiteralValue( dVal );
+ }
+ else {
+ return LiteralValue::createPlainLiteral( s );
+ }
+ }
+}
+
+
QDebug operator<<( QDebug s, const Soprano::Node& n )
{
switch( n.type() ) {
_______________________________________________
Nepomuk mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/nepomuk