From cf885e7ba9c8b17c71230143879de0c6366aab7a Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Mon, 26 Sep 2022 12:02:29 +0200 Subject: [PATCH] Fix SLD rule text fields quoting Fixes #42348 --- .../qgscategorizedsymbolrenderer.cpp | 4 +- tests/src/python/test_qgssymbollayer.py | 49 ++++++++++++++++++- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/core/symbology/qgscategorizedsymbolrenderer.cpp b/src/core/symbology/qgscategorizedsymbolrenderer.cpp index a36a95a0a07a..0c990f8248cb 100644 --- a/src/core/symbology/qgscategorizedsymbolrenderer.cpp +++ b/src/core/symbology/qgscategorizedsymbolrenderer.cpp @@ -148,13 +148,13 @@ void QgsRendererCategory::toSld( QDomDocument &doc, QDomElement &element, QVaria if ( QgsVariantUtils::isNull( mValue ) || mValue.toString().isEmpty() ) { filterFunc = QStringLiteral( "%1 = '%2' or %1 is null" ) - .arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ), + .arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ).append( '"' ).prepend( '"' ), mValue.toString().replace( '\'', QLatin1String( "''" ) ) ); } else { filterFunc = QStringLiteral( "%1 = '%2'" ) - .arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ), + .arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ).append( '"' ).prepend( '"' ), mValue.toString().replace( '\'', QLatin1String( "''" ) ) ); } diff --git a/tests/src/python/test_qgssymbollayer.py b/tests/src/python/test_qgssymbollayer.py index 6c4f65fcbbf9..4ca8d73070e9 100644 --- a/tests/src/python/test_qgssymbollayer.py +++ b/tests/src/python/test_qgssymbollayer.py @@ -26,11 +26,12 @@ import qgis # NOQA +from osgeo import ogr import os from distutils.version import StrictVersion from qgis.PyQt.Qt import PYQT_VERSION_STR -from qgis.PyQt.QtCore import Qt, QObject, QDir, QFile, QIODevice, QPointF, QSize +from qgis.PyQt.QtCore import Qt, QObject, QDir, QFile, QIODevice, QPointF, QSize, QTemporaryDir from qgis.PyQt.QtXml import QDomDocument from qgis.PyQt.QtGui import QColor, QImage, QPainter @@ -75,7 +76,9 @@ QgsSingleSymbolRenderer, QgsProperty, QgsExpressionContext, - QgsExpressionContextUtils + QgsExpressionContextUtils, + QgsCategorizedSymbolRenderer, + QgsRendererCategory, ) from qgis.testing import start_app, unittest from utilities import unitTestDataPath @@ -1149,6 +1152,48 @@ def testQgsSvgMarkerSymbolLayer(self): ctx = QgsRenderContext() self.assertCountEqual(mSymbolLayer.usedAttributes(ctx), {}) + def testSldRuleExport(self): + """Test issue GH #4234 fields containing spaces""" + + temp_dir = QTemporaryDir() + temp_path = temp_dir.path() + temp_gpkg = os.path.join(temp_path, 'test.gpkg') + + ds = ogr.GetDriverByName('GPKG').CreateDataSource(temp_gpkg) + + lyr = ds.CreateLayer("test_layer", geom_type=ogr.wkbPoint, options=['SPATIAL_INDEX=NO']) + lyr.CreateField(ogr.FieldDefn('Text Field With Spaces', ogr.OFTString)) + f = ogr.Feature(lyr.GetLayerDefn()) + f['Text Field With Spaces'] = 'foo' + f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(%s %s)' % (1, 1 + 0.01))) + lyr.CreateFeature(f) + f = ogr.Feature(lyr.GetLayerDefn()) + f['Text Field With Spaces'] = 'bar' + f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(%s %s)' % (2 + 0.03, 2 + 0.04))) + lyr.CreateFeature(f) + f = None + + vl = QgsVectorLayer(temp_gpkg, 'temp', 'ogr') + + self.assertTrue(vl.isValid()) + + # Create style + + foo_sym = QgsFillSymbol.createSimple({'color': '#ff0000', 'outline_color': 'foo'}) + bar_sym = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': 'bar'}) + + renderer = QgsCategorizedSymbolRenderer() + renderer.setClassAttribute('Text Field With Spaces') + + renderer.addCategory(QgsRendererCategory('foo', foo_sym, 'foo')) + renderer.addCategory(QgsRendererCategory('bar', bar_sym, 'bar')) + + vl.setRenderer(renderer) + + doc = QDomDocument() + vl.exportSldStyle(doc, None) + self.assertFalse('Parser Error' in doc.toString()) + def testQgsFilledMarkerSymbolLayer(self): """ Test QgsFilledMarkerSymbolLayer