46       void addTransactionResult( QDomDocument &responseDoc, QDomElement &responseElem, 
const QString &status,
 
   47                                  const QString &locator, 
const QString &message );
 
   58       response.
setHeader( 
"Content-Type", 
"text/xml; charset=utf-8" );
 
   59       response.
write( doc.toByteArray() );
 
   68       transactionRequest aRequest;
 
   73       if ( doc.setContent( request.
data(), 
true, &errorMsg ) )
 
   75         QDomElement docElem = doc.documentElement();
 
   83       int actionCount = aRequest.inserts.size() + aRequest.updates.size() + aRequest.deletes.size();
 
   84       if ( actionCount == 0 )
 
   86         throw QgsRequestNotWellFormedException( QStringLiteral( 
"No actions found" ) );
 
   95       QDomElement respElem = resp.createElement( QStringLiteral( 
"WFS_TransactionResponse" ) );
 
   96       respElem.setAttribute( QStringLiteral( 
"xmlns" ), 
WFS_NAMESPACE );
 
   97       respElem.setAttribute( QStringLiteral( 
"xmlns:xsi" ), QStringLiteral( 
"http://www.w3.org/2001/XMLSchema-instance" ) );
 
   98       respElem.setAttribute( QStringLiteral( 
"xsi:schemaLocation" ), 
WFS_NAMESPACE + 
" http://schemas.opengis.net/wfs/1.0.0/wfs.xsd" );
 
   99       respElem.setAttribute( QStringLiteral( 
"xmlns:ogc" ), 
OGC_NAMESPACE );
 
  100       respElem.setAttribute( QStringLiteral( 
"version" ), QStringLiteral( 
"1.0.0" ) );
 
  101       resp.appendChild( respElem );
 
  104       QStringList errorLocators;
 
  105       QStringList errorMessages;
 
  107       QList<transactionUpdate>::iterator tuIt = aRequest.updates.begin();
 
  108       for ( ; tuIt != aRequest.updates.end(); ++tuIt )
 
  114           if ( action.
handle.isEmpty() )
 
  116             errorLocators << QStringLiteral( 
"Update:%1" ).arg( action.
typeName );
 
  120             errorLocators << action.
handle;
 
  126       QList<transactionDelete>::iterator tdIt = aRequest.deletes.begin();
 
  127       for ( ; tdIt != aRequest.deletes.end(); ++tdIt )
 
  133           if ( action.
handle.isEmpty() )
 
  135             errorLocators << QStringLiteral( 
"Delete:%1" ).arg( action.
typeName );
 
  139             errorLocators << action.
handle;
 
  145       QList<transactionInsert>::iterator tiIt = aRequest.inserts.begin();
 
  146       for ( ; tiIt != aRequest.inserts.end(); ++tiIt )
 
  148         transactionInsert &action = *tiIt;
 
  152           if ( action.handle.isEmpty() )
 
  154             errorLocators << QStringLiteral( 
"Insert:%1" ).arg( action.typeName );
 
  158             errorLocators << action.
handle;
 
  160           errorMessages << action.errorMsg;
 
  164           QStringList::const_iterator fidIt = action.insertFeatureIds.constBegin();
 
  165           for ( ; fidIt != action.insertFeatureIds.constEnd(); ++fidIt )
 
  167             QString fidStr = *fidIt;
 
  168             QDomElement irElem = doc.createElement( QStringLiteral( 
"InsertResult" ) );
 
  169             if ( !action.handle.isEmpty() )
 
  171               irElem.setAttribute( QStringLiteral( 
"handle" ), action.handle );
 
  173             QDomElement fiElem = doc.createElement( QStringLiteral( 
"ogc:FeatureId" ) );
 
  174             fiElem.setAttribute( QStringLiteral( 
"fid" ), fidStr );
 
  175             irElem.appendChild( fiElem );
 
  176             respElem.appendChild( irElem );
 
  182       if ( errorCount == 0 )
 
  184         addTransactionResult( resp, respElem, QStringLiteral( 
"SUCCESS" ), QString(), QString() );
 
  188         QString locator = errorLocators.join( QLatin1String( 
"; " ) );
 
  189         QString message = errorMessages.join( QLatin1String( 
"; " ) );
 
  190         if ( errorCount != actionCount )
 
  192           addTransactionResult( resp, respElem, QStringLiteral( 
"PARTIAL" ), locator, message );
 
  196           addTransactionResult( resp, respElem, QStringLiteral( 
"ERROR" ), locator, message );
 
  205       QStringList typeNameList;
 
  207       QList<transactionInsert>::iterator tiIt = aRequest.inserts.begin();
 
  208       for ( ; tiIt != aRequest.inserts.end(); ++tiIt )
 
  210         QString name = ( *tiIt ).typeName;
 
  211         if ( !typeNameList.contains( name ) )
 
  212           typeNameList << name;
 
  214       QList<transactionUpdate>::iterator tuIt = aRequest.updates.begin();
 
  215       for ( ; tuIt != aRequest.updates.end(); ++tuIt )
 
  217         QString name = ( *tuIt ).typeName;
 
  218         if ( !typeNameList.contains( name ) )
 
  219           typeNameList << name;
 
  221       QList<transactionDelete>::iterator tdIt = aRequest.deletes.begin();
 
  222       for ( ; tdIt != aRequest.deletes.end(); ++tdIt )
 
  224         QString name = ( *tdIt ).typeName;
 
  225         if ( !typeNameList.contains( name ) )
 
  226           typeNameList << name;
 
  229 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  245       QMap<QString, QgsVectorLayer *> mapLayerMap;
 
  256         if ( !typeNameList.contains( name ) )
 
  265           throw QgsRequestNotWellFormedException( QStringLiteral( 
"Layer error on '%1'" ).arg( name ) );
 
  272           throw QgsRequestNotWellFormedException( QStringLiteral( 
"Provider error on layer '%1'" ).arg( name ) );
 
  280           throw QgsRequestNotWellFormedException( QStringLiteral( 
"No capabilities to do WFS changes on layer '%1'" ).arg( name ) );
 
  287           throw QgsSecurityAccessException( QStringLiteral( 
"No permissions to do WFS changes on layer '%1'" ).arg( name ) );
 
  289 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  293           throw QgsSecurityAccessException( QStringLiteral( 
"No permissions to do WFS changes on layer '%1'" ).arg( name ) );
 
  302         mapLayerMap[name] = vlayer;
 
  306       tuIt = aRequest.updates.begin();
 
  307       for ( ; tuIt != aRequest.updates.end(); ++tuIt )
 
  309         transactionUpdate &action = *tuIt;
 
  312         if ( !mapLayerMap.keys().contains( 
typeName ) )
 
  315           action.errorMsg = QStringLiteral( 
"TypeName '%1' unknown" ).arg( 
typeName );
 
  326           action.errorMsg = QStringLiteral( 
"No permissions to do WFS updates on layer '%1'" ).arg( 
typeName );
 
  329 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  333           action.errorMsg = QStringLiteral( 
"No permissions to do WFS updates on layer '%1'" ).arg( 
typeName );
 
  345           action.errorMsg = QStringLiteral( 
"No capabilities to do WFS updates on layer '%1'" ).arg( 
typeName );
 
  362         if ( !action.serverFids.isEmpty() )
 
  368 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  378         QMap<QString, QString> propertyMap = action.propertyMap;
 
  379         QDomElement geometryElem = action.geometryElement;
 
  382         const QMap<QString, int> fieldMap = provider->
fieldNameMap();
 
  383         QMap<QString, int>::const_iterator fieldMapIt;
 
  385         bool conversionSuccess;
 
  389 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  390           if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
 
  393             action.errorMsg = QStringLiteral( 
"Feature modify permission denied on layer '%1'" ).arg( 
typeName );
 
  398           QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
 
  399           for ( ; it != propertyMap.constEnd(); ++it )
 
  401             fieldName = it.key();
 
  402             fieldMapIt = fieldMap.find( fieldName );
 
  403             if ( fieldMapIt == fieldMap.constEnd() )
 
  408             QVariant value = it.value();
 
  409             if ( value.isNull() )
 
  414                 action.errorMsg = QStringLiteral( 
"NOT NULL constraint error on layer '%1', field '%2'" ).arg( 
typeName, 
field.
name() );
 
  421               if ( 
field.
type() == QVariant::Type::Int )
 
  423                 value = it.value().toInt( &conversionSuccess );
 
  424                 if ( !conversionSuccess )
 
  427                   action.errorMsg = QStringLiteral( 
"Property conversion error on layer '%1'" ).arg( 
typeName );
 
  432               else if ( 
field.
type() == QVariant::Type::Double )
 
  434                 value = it.value().toDouble( &conversionSuccess );
 
  435                 if ( !conversionSuccess )
 
  438                   action.errorMsg = QStringLiteral( 
"Property conversion error on layer '%1'" ).arg( 
typeName );
 
  443               else if ( 
field.
type() == QVariant::Type::LongLong )
 
  445                 value = it.value().toLongLong( &conversionSuccess );
 
  446                 if ( !conversionSuccess )
 
  449                   action.errorMsg = QStringLiteral( 
"Property conversion error on layer '%1'" ).arg( 
typeName );
 
  462           if ( !geometryElem.isNull() )
 
  470               action.errorMsg = QStringLiteral( 
"Geometry from GML error on layer '%1'" ).arg( 
typeName );
 
  477               action.errorMsg = QStringLiteral( 
"Error in change geometry on layer '%1'" ).arg( 
typeName );
 
  487 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  494             if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
 
  497               action.errorMsg = QStringLiteral( 
"Feature modify permission denied on layer '%1'" ).arg( 
typeName );
 
  513           action.errorMsg = QStringLiteral( 
"Error committing updates: %1" ).arg( vlayer->
commitErrors().join( QLatin1String( 
"; " ) ) );
 
  518         action.error = 
false;
 
  523       tdIt = aRequest.deletes.begin();
 
  524       for ( ; tdIt != aRequest.deletes.end(); ++tdIt )
 
  526         transactionDelete &action = *tdIt;
 
  529         if ( !mapLayerMap.keys().contains( 
typeName ) )
 
  532           action.errorMsg = QStringLiteral( 
"TypeName '%1' unknown" ).arg( 
typeName );
 
  543           action.errorMsg = QStringLiteral( 
"No permissions to do WFS deletes on layer '%1'" ).arg( 
typeName );
 
  546 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  550           action.errorMsg = QStringLiteral( 
"No permissions to do WFS deletes on layer '%1'" ).arg( 
typeName );
 
  562           action.errorMsg = QStringLiteral( 
"No capabilities to do WFS deletes on layer '%1'" ).arg( 
typeName );
 
  579         if ( action.serverFids.isEmpty() )
 
  582           action.errorMsg = QStringLiteral( 
"No feature ids to do WFS deletes on layer '%1'" ).arg( 
typeName );
 
  589 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  603 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  604           if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
 
  607             action.errorMsg = QStringLiteral( 
"Feature modify permission denied" );
 
  612           fids << feature.
id();
 
  622           action.errorMsg = QStringLiteral( 
"Delete features failed on layer '%1'" ).arg( 
typeName );
 
  631           action.errorMsg = QStringLiteral( 
"Error committing deletes: %1" ).arg( vlayer->
commitErrors().join( QLatin1String( 
"; " ) ) );
 
  636         action.error = 
false;
 
  640       tiIt = aRequest.inserts.begin();
 
  641       for ( ; tiIt != aRequest.inserts.end(); ++tiIt )
 
  643         transactionInsert &action = *tiIt;
 
  646         if ( !mapLayerMap.keys().contains( 
typeName ) )
 
  649           action.errorMsg = QStringLiteral( 
"TypeName '%1' unknown" ).arg( 
typeName );
 
  660           action.errorMsg = QStringLiteral( 
"No permissions to do WFS inserts on layer '%1'" ).arg( 
typeName );
 
  663 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  667           action.errorMsg = QStringLiteral( 
"No permissions to do WFS inserts on layer '%1'" ).arg( 
typeName );
 
  679           action.errorMsg = QStringLiteral( 
"No capabilities to do WFS inserts on layer '%1'" ).arg( 
typeName );
 
  695           action.errorMsg = QStringLiteral( 
"%1 '%2'" ).arg( ex.
message(), 
typeName );
 
  699         if ( featureList.empty() )
 
  702           action.errorMsg = QStringLiteral( 
"No features to insert in layer '%1'" ).arg( 
typeName );
 
  706 #ifdef HAVE_SERVER_PYTHON_PLUGINS 
  710           QgsFeatureList::iterator featureIt = featureList.begin();
 
  711           while ( featureIt != featureList.end() )
 
  713             if ( !accessControl->
allowToEdit( vlayer, *featureIt ) )
 
  716               action.errorMsg = QStringLiteral( 
"Feature modify permission denied on layer '%1'" ).arg( 
typeName );
 
  733           action.errorMsg = QStringLiteral( 
"Insert features failed on layer '%1'" ).arg( 
typeName );
 
  734           if ( provider ->hasErrors() )
 
  746           action.errorMsg = QStringLiteral( 
"Error committing inserts: %1" ).arg( vlayer->
commitErrors().join( QLatin1String( 
"; " ) ) );
 
  751         action.error = 
false;
 
  755         for ( 
const QgsFeature &feat : std::as_const( featureList ) )
 
  762       filterRestorer.reset();
 
  771       Q_ASSERT( provider );
 
  775       const QMap<QString, int> fieldMap = provider->
fieldNameMap();
 
  776       QMap<QString, int>::const_iterator fieldMapIt;
 
  778       for ( 
int i = 0; i < featureNodeList.count(); i++ )
 
  782         QDomElement featureElem = featureNodeList.at( i ).toElement();
 
  783         QDomNode currentAttributeChild = featureElem.firstChild();
 
  784         bool conversionSuccess = 
true;
 
  786         while ( !currentAttributeChild.isNull() )
 
  788           QDomElement currentAttributeElement = currentAttributeChild.toElement();
 
  789           QString attrName = currentAttributeElement.localName();
 
  791           if ( attrName != QLatin1String( 
"boundedBy" ) )
 
  793             if ( attrName != QLatin1String( 
"geometry" ) ) 
 
  795               fieldMapIt = fieldMap.find( attrName );
 
  796               if ( fieldMapIt == fieldMap.constEnd() )
 
  802               QString attrValue = currentAttributeElement.text();
 
  805               QgsMessageLog::logMessage( QStringLiteral( 
"attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
 
  807               if ( attrType == QVariant::Int )
 
  808                 feat.setAttribute( fieldMapIt.value(), attrValue.toInt( &conversionSuccess ) );
 
  809               else if ( attrType == QVariant::Double )
 
  810                 feat.setAttribute( fieldMapIt.value(), attrValue.toDouble( &conversionSuccess ) );
 
  812                 feat.setAttribute( fieldMapIt.value(), attrValue );
 
  814               if ( !conversionSuccess )
 
  825                 throw QgsRequestNotWellFormedException( QStringLiteral( 
"Geometry from GML error on layer insert" ) );
 
  827               feat.setGeometry( g );
 
  830           currentAttributeChild = currentAttributeChild.nextSibling();
 
  840       if ( !parameters.contains( QStringLiteral( 
"OPERATION" ) ) )
 
  842         throw QgsRequestNotWellFormedException( QStringLiteral( 
"OPERATION parameter is mandatory" ) );
 
  844       if ( parameters.value( QStringLiteral( 
"OPERATION" ) ).toUpper() != QLatin1String( 
"DELETE" ) )
 
  846         throw QgsRequestNotWellFormedException( QStringLiteral( 
"Only DELETE value is defined for OPERATION parameter" ) );
 
  850       if ( ( parameters.contains( QStringLiteral( 
"FEATUREID" ) )
 
  851              && ( parameters.contains( QStringLiteral( 
"FILTER" ) ) || parameters.contains( QStringLiteral( 
"BBOX" ) ) ) )
 
  852            || ( parameters.contains( QStringLiteral( 
"FILTER" ) )
 
  853                 && ( parameters.contains( QStringLiteral( 
"FEATUREID" ) ) || parameters.contains( QStringLiteral( 
"BBOX" ) ) ) )
 
  854            || ( parameters.contains( QStringLiteral( 
"BBOX" ) )
 
  855                 && ( parameters.contains( QStringLiteral( 
"FEATUREID" ) ) || parameters.contains( QStringLiteral( 
"FILTER" ) ) ) )
 
  858         throw QgsRequestNotWellFormedException( QStringLiteral( 
"FEATUREID FILTER and BBOX parameters are mutually exclusive" ) );
 
  861       transactionRequest request;
 
  863       QStringList typeNameList;
 
  865       if ( parameters.contains( QStringLiteral( 
"FEATUREID" ) ) )
 
  867         QStringList fidList = parameters.value( QStringLiteral( 
"FEATUREID" ) ).split( 
',' );
 
  869         QMap<QString, QStringList> fidsMap;
 
  871         QStringList::const_iterator fidIt = fidList.constBegin();
 
  872         for ( ; fidIt != fidList.constEnd(); ++fidIt )
 
  875           QString fid = *fidIt;
 
  878           if ( !fid.contains( 
'.' ) )
 
  883           QString 
typeName = fid.section( 
'.', 0, 0 );
 
  884           fid = fid.section( 
'.', 1, 1 );
 
  885           if ( !typeNameList.contains( 
typeName ) )
 
  899         QMap<QString, QStringList>::const_iterator fidsMapIt = fidsMap.constBegin();
 
  900         while ( fidsMapIt != fidsMap.constEnd() )
 
  902           transactionDelete action;
 
  903           action.typeName = fidsMapIt.key();
 
  905           action.serverFids = fidsMapIt.value();
 
  908           request.deletes.append( action );
 
  913       if ( !parameters.contains( QStringLiteral( 
"TYPENAME" ) ) )
 
  915         throw QgsRequestNotWellFormedException( QStringLiteral( 
"TYPENAME is mandatory except if FEATUREID is used" ) );
 
  918       typeNameList = parameters.value( QStringLiteral( 
"TYPENAME" ) ).split( 
',' );
 
  921       QStringList::const_iterator typeNameIt = typeNameList.constBegin();
 
  922       for ( ; typeNameIt != typeNameList.constEnd(); ++typeNameIt )
 
  927         transactionDelete action;
 
  930         request.deletes.append( action );
 
  934       if ( parameters.contains( QStringLiteral( 
"EXP_FILTER" ) ) )
 
  936         QString expFilterName = parameters.value( QStringLiteral( 
"EXP_FILTER" ) );
 
  937         QStringList expFilterList;
 
  938         QRegExp rx( 
"\\(([^()]+)\\)" );
 
  939         if ( rx.indexIn( expFilterName, 0 ) == -1 )
 
  941           expFilterList << expFilterName;
 
  946           while ( ( pos = rx.indexIn( expFilterName, pos ) ) != -1 )
 
  948             expFilterList << rx.cap( 1 );
 
  949             pos += rx.matchedLength();
 
  954         if ( request.deletes.size() == expFilterList.size() )
 
  957           QList<transactionDelete>::iterator dIt = request.deletes.begin();
 
  958           QStringList::const_iterator expFilterIt = expFilterList.constBegin();
 
  959           for ( ; dIt != request.deletes.end(); ++dIt )
 
  961             transactionDelete &action = *dIt;
 
  964             if ( expFilterIt != expFilterList.constEnd() )
 
  966               expFilter = *expFilterIt;
 
  968             std::shared_ptr<QgsExpression> filter( 
new QgsExpression( expFilter ) );
 
  971               if ( filter->hasParserError() )
 
  977                 if ( filter->needsGeometry() )
 
  981                 action.featureRequest.setFilterExpression( filter->expression() );
 
  992       if ( parameters.contains( QStringLiteral( 
"BBOX" ) ) )
 
  995         QString bbox = parameters.value( QStringLiteral( 
"BBOX" ) );
 
  996         if ( bbox.isEmpty() )
 
  998           throw QgsRequestNotWellFormedException( QStringLiteral( 
"BBOX parameter is empty" ) );
 
 1002         QStringList corners = bbox.split( 
',' );
 
 1003         if ( corners.size() != 4 )
 
 1005           throw QgsRequestNotWellFormedException( QStringLiteral( 
"BBOX has to be composed of 4 elements: '%1'" ).arg( bbox ) );
 
 1011         for ( 
int i = 0; i < 4; i++ )
 
 1013           corners[i].replace( 
' ', 
'+' );
 
 1014           d[i] = corners[i].toDouble( &ok );
 
 1017             throw QgsRequestNotWellFormedException( QStringLiteral( 
"BBOX has to be composed of 4 double: '%1'" ).arg( bbox ) );
 
 1024         QList<transactionDelete>::iterator dIt = request.deletes.begin();
 
 1025         for ( ; dIt != request.deletes.end(); ++dIt )
 
 1027           transactionDelete &action = *dIt;
 
 1028           action.featureRequest.setFilterRect( extent );
 
 1032       else if ( parameters.contains( QStringLiteral( 
"FILTER" ) ) )
 
 1034         QString filterName = parameters.value( QStringLiteral( 
"FILTER" ) );
 
 1035         QStringList filterList;
 
 1036         QRegExp rx( 
"\\(([^()]+)\\)" );
 
 1037         if ( rx.indexIn( filterName, 0 ) == -1 )
 
 1039           filterList << filterName;
 
 1044           while ( ( pos = rx.indexIn( filterName, pos ) ) != -1 )
 
 1046             filterList << rx.cap( 1 );
 
 1047             pos += rx.matchedLength();
 
 1052         if ( request.deletes.size() != filterList.size() )
 
 1054           throw QgsRequestNotWellFormedException( QStringLiteral( 
"There has to be a 1:1 mapping between each element in a TYPENAME and the FILTER list" ) );
 
 1058         QList<transactionDelete>::iterator dIt = request.deletes.begin();
 
 1059         QStringList::const_iterator filterIt = filterList.constBegin();
 
 1060         for ( ; dIt != request.deletes.end(); ++dIt )
 
 1062           transactionDelete &action = *dIt;
 
 1065           QDomDocument filter;
 
 1066           if ( filterIt != filterList.constEnd() )
 
 1069             if ( !filter.setContent( *filterIt, 
true, &errorMsg ) )
 
 1071               throw QgsRequestNotWellFormedException( QStringLiteral( 
"error message: %1. The XML string was: %2" ).arg( errorMsg, *filterIt ) );
 
 1075           QDomElement filterElem = filter.firstChildElement();
 
 1076           QStringList serverFids;
 
 1077           action.featureRequest = 
parseFilterElement( action.typeName, filterElem, serverFids, project );
 
 1078           action.serverFids = serverFids;
 
 1080           if ( filterIt != filterList.constEnd() )
 
 1093       transactionRequest request;
 
 1095       QDomNodeList docChildNodes = docElem.childNodes();
 
 1097       QDomElement actionElem;
 
 1100       for ( 
int i = docChildNodes.count(); 0 < i; --i )
 
 1102         actionElem = docChildNodes.at( i - 1 ).toElement();
 
 1103         actionName = actionElem.localName();
 
 1105         if ( actionName == QLatin1String( 
"Insert" ) )
 
 1108           request.inserts.append( action );
 
 1110         else if ( actionName == QLatin1String( 
"Update" ) )
 
 1113           request.updates.append( action );
 
 1115         else if ( actionName == QLatin1String( 
"Delete" ) )
 
 1118           request.deletes.append( action );
 
 1127       QString 
typeName = actionElem.attribute( QStringLiteral( 
"typeName" ) );
 
 1131       QDomElement filterElem = actionElem.firstChild().toElement();
 
 1132       if ( filterElem.tagName() != QLatin1String( 
"Filter" ) )
 
 1137       QStringList serverFids;
 
 1144       action.
error = 
false;
 
 1146       if ( actionElem.hasAttribute( QStringLiteral( 
"handle" ) ) )
 
 1148         action.
handle = actionElem.attribute( QStringLiteral( 
"handle" ) );
 
 1156       QString 
typeName = actionElem.attribute( QStringLiteral( 
"typeName" ) );
 
 1160       QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral( 
"Property" ) );
 
 1161       if ( propertyNodeList.isEmpty() )
 
 1166       QMap<QString, QString> propertyMap;
 
 1167       QDomElement propertyElem;
 
 1168       QDomElement nameElem;
 
 1169       QDomElement valueElem;
 
 1170       QDomElement geometryElem;
 
 1172       for ( 
int l = 0; l < propertyNodeList.count(); ++l )
 
 1174         propertyElem = propertyNodeList.at( l ).toElement();
 
 1175         nameElem = propertyElem.elementsByTagName( QStringLiteral( 
"Name" ) ).at( 0 ).toElement();
 
 1176         valueElem = propertyElem.elementsByTagName( QStringLiteral( 
"Value" ) ).at( 0 ).toElement();
 
 1177         if ( nameElem.text() != QLatin1String( 
"geometry" ) )
 
 1179           propertyMap.insert( nameElem.text(), valueElem.text() );
 
 1183           geometryElem = valueElem;
 
 1187       QDomNodeList filterNodeList = actionElem.elementsByTagName( QStringLiteral( 
"Filter" ) );
 
 1189       QStringList serverFids;
 
 1190       if ( filterNodeList.size() != 0 )
 
 1192         QDomElement filterElem = filterNodeList.at( 0 ).toElement();
 
 1202       action.
error = 
false;
 
 1204       if ( actionElem.hasAttribute( QStringLiteral( 
"handle" ) ) )
 
 1206         action.
handle = actionElem.attribute( QStringLiteral( 
"handle" ) );
 
 1214       QDomNodeList featureNodeList = actionElem.childNodes();
 
 1215       if ( featureNodeList.size() != 1 )
 
 1217         throw QgsRequestNotWellFormedException( QStringLiteral( 
"Insert action element must have one or more child node" ) );
 
 1221       for ( 
int i = 0; i < featureNodeList.count(); ++i )
 
 1223         QString tempTypeName = featureNodeList.at( i ).toElement().localName();
 
 1224         if ( tempTypeName.contains( 
':' ) )
 
 1225           tempTypeName = tempTypeName.section( 
':', 1, 1 );
 
 1231         else if ( tempTypeName != 
typeName )
 
 1233           throw QgsRequestNotWellFormedException( QStringLiteral( 
"Insert action element must have one typename features" ) );
 
 1237       transactionInsert action;
 
 1239       action.featureNodeList = featureNodeList;
 
 1240       action.error = 
false;
 
 1242       if ( actionElem.hasAttribute( QStringLiteral( 
"handle" ) ) )
 
 1244         action.handle = actionElem.attribute( QStringLiteral( 
"handle" ) );
 
 1253       void addTransactionResult( QDomDocument &responseDoc, QDomElement &responseElem, 
const QString &status,
 
 1254                                  const QString &locator, 
const QString &message )
 
 1256         QDomElement trElem = responseDoc.createElement( QStringLiteral( 
"TransactionResult" ) );
 
 1257         QDomElement stElem = responseDoc.createElement( QStringLiteral( 
"Status" ) );
 
 1258         QDomElement successElem = responseDoc.createElement( status );
 
 1259         stElem.appendChild( successElem );
 
 1260         trElem.appendChild( stElem );
 
 1261         responseElem.appendChild( trElem );
 
 1263         if ( !locator.isEmpty() )
 
 1265           QDomElement locElem = responseDoc.createElement( QStringLiteral( 
"Locator" ) );
 
 1266           locElem.appendChild( responseDoc.createTextNode( locator ) );
 
 1267           trElem.appendChild( locElem );
 
 1270         if ( !message.isEmpty() )
 
 1272           QDomElement mesElem = responseDoc.createElement( QStringLiteral( 
"Message" ) );
 
 1273           mesElem.appendChild( responseDoc.createTextNode( message ) );
 
 1274           trElem.appendChild( mesElem );