Commit 95148e36 authored by Julien Osman's avatar Julien Osman

BUG: Add ReadXMLToList to XMLMetadataSupplier

ReadXMLToList from GDAL is not part of the public API. It can be used
when compiling libgdal without --with-hide-internal-symbols
switch. But libgdal from Debian and Ubuntu packages doesn't contains
the symbols. The adopted solution is to implement a ReadXMLToList
function for the OTB.
parent 978e0603
Pipeline #5119 passed with stages
in 26 minutes and 1 second
......@@ -21,7 +21,8 @@
#ifndef otbXMLMetadataSupplier_h
#define otbXMLMetadataSupplier_h
#include <gdal_mdreader.h>
#include "cpl_minixml.h"
#include "cpl_string.h"
#include "OTBMetadataExport.h"
#include "otbMetadataSupplierInterface.h"
......@@ -38,8 +39,7 @@ namespace otb
* \ingroup OTBMetadata
*/
class OTBMetadata_EXPORT XMLMetadataSupplier
: public MetadataSupplierInterface,
public GDALMDReaderBase
: public MetadataSupplierInterface
{
public:
XMLMetadataSupplier(const std::string &);
......@@ -52,18 +52,18 @@ public:
std::string GetResourceFile() const override;
/**
* @brief Determine whether the input parameter correspond to the particular
* provider of remote sensing data completely
* @return True if all needed sources files found
* @brief ReadXMLToList Transform xml to list of NULL terminated name=value
* strings
* @param psNode A xml node to process
* @param papszList A list to fill with name=value strings
* @param pszName A name of parent node. For root xml node should be empty.
* If name is not empty, the sibling nodes will not proceed
* @return An input list filled with values
*
* This method originates from a work by GDAL in the class GDALMDReaderBase.
*/
bool HasRequiredFiles() const override;
/**
* @brief Get metadata file names. The caller become owner of returned list
* and have to free it via CSLDestroy.
* @return A file name list
*/
char** GetMetadataFiles() const override;
virtual char** ReadXMLToList(CPLXMLNode* psNode, char** papszList,
const char* pszName = "");
private:
/** List of resource files */
......
......@@ -23,7 +23,7 @@
namespace otb
{
XMLMetadataSupplier::XMLMetadataSupplier(const std::string & fileName)
: GDALMDReaderBase(nullptr, nullptr), m_FileName(fileName)
: m_FileName(fileName)
{
CPLXMLNode* psNode = CPLParseXMLFile(m_FileName.c_str());
if(psNode != nullptr)
......@@ -50,15 +50,110 @@ std::string XMLMetadataSupplier::GetResourceFile() const
return m_FileName;
}
bool XMLMetadataSupplier::HasRequiredFiles() const
// This method originates from a work by GDAL in the class GDALMDReaderBase.
char** XMLMetadataSupplier::ReadXMLToList(CPLXMLNode* psNode, char** papszList,
const char* pszName)
{
return false; // TODO
}
if(nullptr == psNode)
return papszList;
char** XMLMetadataSupplier::GetMetadataFiles() const
{
char ** todo;
return todo; // TODO
if (psNode->eType == CXT_Text)
{
papszList = CSLAddNameValue(papszList, pszName, psNode->pszValue);
}
if (psNode->eType == CXT_Element)
{
int nAddIndex = 0;
bool bReset = false;
for(CPLXMLNode* psChildNode = psNode->psChild; nullptr != psChildNode;
psChildNode = psChildNode->psNext)
{
if (psChildNode->eType == CXT_Element)
{
// check name duplicates
if(nullptr != psChildNode->psNext)
{
if(bReset)
{
bReset = false;
nAddIndex = 0;
}
if(EQUAL(psChildNode->pszValue, psChildNode->psNext->pszValue))
{
nAddIndex++;
}
else
{ // the name changed
if(nAddIndex > 0)
{
bReset = true;
nAddIndex++;
}
}
}
else
{
if(bReset)
{
bReset = false;
nAddIndex = 0;
}
if(nAddIndex > 0)
{
nAddIndex++;
}
}
char szName[512];
if(nAddIndex > 0)
{
CPLsnprintf( szName, 511, "%s_%d", psChildNode->pszValue,
nAddIndex);
}
else
{
CPLStrlcpy(szName, psChildNode->pszValue, 511);
}
char szNameNew[512];
if(CPLStrnlen( pszName, 511 ) > 0) //if no prefix just set name to node name
{
CPLsnprintf( szNameNew, 511, "%s.%s", pszName, szName );
}
else
{
CPLsnprintf( szNameNew, 511, "%s.%s", psNode->pszValue, szName );
}
papszList = ReadXMLToList(psChildNode, papszList, szNameNew);
}
else if( psChildNode->eType == CXT_Attribute )
{
papszList = CSLAddNameValue(papszList,
CPLSPrintf("%s.%s", pszName, psChildNode->pszValue),
psChildNode->psChild->pszValue);
}
else
{
// Text nodes should always have name
if(EQUAL(pszName, ""))
{
papszList = ReadXMLToList(psChildNode, papszList, psNode->pszValue);
}
else
{
papszList = ReadXMLToList(psChildNode, papszList, pszName);
}
}
}
}
// proceed next only on top level
if(nullptr != psNode->psNext && EQUAL(pszName, ""))
{
papszList = ReadXMLToList(psNode->psNext, papszList, pszName);
}
return papszList;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment