Skip to content

Commit

Permalink
XLSX: support documents whose XML elements have a prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault authored and github-actions[bot] committed Aug 10, 2024
1 parent 1e95085 commit 5b61064
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 14 deletions.
Binary file added autotest/ogr/data/xlsx/with_xml_prefix.xlsx
Binary file not shown.
15 changes: 15 additions & 0 deletions autotest/ogr/ogr_xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
45 changes: 31 additions & 14 deletions ogr/ogrsf_frmts/xlsx/ogrxlsxdatasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() */
/************************************************************************/
Expand All @@ -434,6 +446,8 @@ void OGRXLSXDataSource::startElementCbk(const char *pszNameIn,
if (bStopParsing)
return;

pszNameIn = GetUnprefixed(pszNameIn);

nWithoutEventCounter = 0;
switch (stateStack[nStackDepth].eVal)
{
Expand Down Expand Up @@ -474,6 +488,8 @@ void OGRXLSXDataSource::endElementCbk(const char *pszNameIn)
if (bStopParsing)
return;

pszNameIn = GetUnprefixed(pszNameIn);

nWithoutEventCounter = 0;

nDepth--;
Expand Down Expand Up @@ -1346,6 +1362,8 @@ void OGRXLSXDataSource::startElementSSCbk(const char *pszNameIn,
if (bStopParsing)
return;

pszNameIn = GetUnprefixed(pszNameIn);

nWithoutEventCounter = 0;
switch (stateStack[nStackDepth].eVal)
{
Expand Down Expand Up @@ -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--;
Expand Down Expand Up @@ -1529,6 +1550,8 @@ void OGRXLSXDataSource::startElementWBRelsCbk(const char *pszNameIn,
if (bStopParsing)
return;

pszNameIn = GetUnprefixed(pszNameIn);

nWithoutEventCounter = 0;
if (strcmp(pszNameIn, "Relationship") == 0)
{
Expand Down Expand Up @@ -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() */
/************************************************************************/
Expand All @@ -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);
Expand Down Expand Up @@ -1725,6 +1738,8 @@ void OGRXLSXDataSource::startElementStylesCbk(const char *pszNameIn,
if (bStopParsing)
return;

pszNameIn = GetUnprefixed(pszNameIn);

nWithoutEventCounter = 0;
if (strcmp(pszNameIn, "numFmt") == 0)
{
Expand Down Expand Up @@ -1810,6 +1825,8 @@ void OGRXLSXDataSource::endElementStylesCbk(const char *pszNameIn)
if (bStopParsing)
return;

pszNameIn = GetUnprefixed(pszNameIn);

nWithoutEventCounter = 0;
if (strcmp(pszNameIn, "cellXfs") == 0)
{
Expand Down

0 comments on commit 5b61064

Please sign in to comment.