diff --git a/autotest/ogr/data/xlsx/with_xml_prefix.xlsx b/autotest/ogr/data/xlsx/with_xml_prefix.xlsx new file mode 100644 index 000000000000..4d23ef8ddf26 Binary files /dev/null and b/autotest/ogr/data/xlsx/with_xml_prefix.xlsx differ diff --git a/autotest/ogr/ogr_xlsx.py b/autotest/ogr/ogr_xlsx.py index 197563a1c964..632df94bcfab 100755 --- a/autotest/ogr/ogr_xlsx.py +++ b/autotest/ogr/ogr_xlsx.py @@ -650,3 +650,18 @@ def test_ogr_xlsx_write_sheet_without_row(): assert ds.GetLayer(2).GetFeatureCount() == 1 ds = None gdal.Unlink(tmpfilename) + + +############################################################################### +# Test reading a XLSX file with XML element prefixes + + +def test_ogr_xlsx_read_xml_prefix(): + + ds = ogr.Open("data/xlsx/with_xml_prefix.xlsx") + lyr = ds.GetLayer(0) + assert lyr.GetLayerDefn().GetFieldDefn(0).GetName() == "Col1" + assert lyr.GetLayerDefn().GetFieldDefn(1).GetName() == "Col2" + f = lyr.GetNextFeature() + assert f["Col1"] == "foo" + assert f["Col2"] == "bar" diff --git a/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp b/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp index 7222ca2ef468..9590b7b5f20b 100644 --- a/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp +++ b/ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp @@ -418,6 +418,18 @@ int OGRXLSXDataSource::Create(const char *pszFilename, return TRUE; } +/************************************************************************/ +/* GetUnprefixed() */ +/************************************************************************/ + +static const char *GetUnprefixed(const char *pszStr) +{ + const char *pszColumn = strchr(pszStr, ':'); + if (pszColumn) + return pszColumn + 1; + return pszStr; +} + /************************************************************************/ /* startElementCbk() */ /************************************************************************/ @@ -434,6 +446,8 @@ void OGRXLSXDataSource::startElementCbk(const char *pszNameIn, if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; switch (stateStack[nStackDepth].eVal) { @@ -474,6 +488,8 @@ void OGRXLSXDataSource::endElementCbk(const char *pszNameIn) if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; nDepth--; @@ -1346,6 +1362,8 @@ void OGRXLSXDataSource::startElementSSCbk(const char *pszNameIn, if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; switch (stateStack[nStackDepth].eVal) { @@ -1381,11 +1399,14 @@ static void XMLCALL endElementSSCbk(void *pUserData, const char *pszNameIn) ((OGRXLSXDataSource *)pUserData)->endElementSSCbk(pszNameIn); } -void OGRXLSXDataSource::endElementSSCbk(CPL_UNUSED const char *pszNameIn) +void OGRXLSXDataSource::endElementSSCbk(const char * /*pszNameIn*/) { if (bStopParsing) return; + // If we were to use pszNameIn, then we need: + // pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; nDepth--; @@ -1529,6 +1550,8 @@ void OGRXLSXDataSource::startElementWBRelsCbk(const char *pszNameIn, if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; if (strcmp(pszNameIn, "Relationship") == 0) { @@ -1593,18 +1616,6 @@ void OGRXLSXDataSource::AnalyseWorkbookRels(VSILFILE *fpWorkbookRels) VSIFCloseL(fpWorkbookRels); } -/************************************************************************/ -/* GetUnprefixed() */ -/************************************************************************/ - -static const char *GetUnprefixed(const char *pszStr) -{ - const char *pszColumn = strchr(pszStr, ':'); - if (pszColumn) - return pszColumn + 1; - return pszStr; -} - /************************************************************************/ /* startElementWBCbk() */ /************************************************************************/ @@ -1621,8 +1632,10 @@ void OGRXLSXDataSource::startElementWBCbk(const char *pszNameIn, if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; - if (strcmp(GetUnprefixed(pszNameIn), "sheet") == 0) + if (strcmp(pszNameIn, "sheet") == 0) { const char *pszSheetName = GetAttributeValue(ppszAttr, "name", nullptr); const char *pszId = GetAttributeValue(ppszAttr, "r:id", nullptr); @@ -1725,6 +1738,8 @@ void OGRXLSXDataSource::startElementStylesCbk(const char *pszNameIn, if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; if (strcmp(pszNameIn, "numFmt") == 0) { @@ -1810,6 +1825,8 @@ void OGRXLSXDataSource::endElementStylesCbk(const char *pszNameIn) if (bStopParsing) return; + pszNameIn = GetUnprefixed(pszNameIn); + nWithoutEventCounter = 0; if (strcmp(pszNameIn, "cellXfs") == 0) {