Skip to content
Snippets Groups Projects
Commit 95148e36 authored by Julien Osman's avatar Julien Osman
Browse files

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
No related branches found
No related tags found
No related merge requests found
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
#ifndef otbXMLMetadataSupplier_h #ifndef otbXMLMetadataSupplier_h
#define otbXMLMetadataSupplier_h #define otbXMLMetadataSupplier_h
#include <gdal_mdreader.h> #include "cpl_minixml.h"
#include "cpl_string.h"
#include "OTBMetadataExport.h" #include "OTBMetadataExport.h"
#include "otbMetadataSupplierInterface.h" #include "otbMetadataSupplierInterface.h"
...@@ -38,8 +39,7 @@ namespace otb ...@@ -38,8 +39,7 @@ namespace otb
* \ingroup OTBMetadata * \ingroup OTBMetadata
*/ */
class OTBMetadata_EXPORT XMLMetadataSupplier class OTBMetadata_EXPORT XMLMetadataSupplier
: public MetadataSupplierInterface, : public MetadataSupplierInterface
public GDALMDReaderBase
{ {
public: public:
XMLMetadataSupplier(const std::string &); XMLMetadataSupplier(const std::string &);
...@@ -52,18 +52,18 @@ public: ...@@ -52,18 +52,18 @@ public:
std::string GetResourceFile() const override; std::string GetResourceFile() const override;
/** /**
* @brief Determine whether the input parameter correspond to the particular * @brief ReadXMLToList Transform xml to list of NULL terminated name=value
* provider of remote sensing data completely * strings
* @return True if all needed sources files found * @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; virtual char** ReadXMLToList(CPLXMLNode* psNode, char** papszList,
const char* pszName = "");
/**
* @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;
private: private:
/** List of resource files */ /** List of resource files */
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
namespace otb namespace otb
{ {
XMLMetadataSupplier::XMLMetadataSupplier(const std::string & fileName) XMLMetadataSupplier::XMLMetadataSupplier(const std::string & fileName)
: GDALMDReaderBase(nullptr, nullptr), m_FileName(fileName) : m_FileName(fileName)
{ {
CPLXMLNode* psNode = CPLParseXMLFile(m_FileName.c_str()); CPLXMLNode* psNode = CPLParseXMLFile(m_FileName.c_str());
if(psNode != nullptr) if(psNode != nullptr)
...@@ -50,15 +50,110 @@ std::string XMLMetadataSupplier::GetResourceFile() const ...@@ -50,15 +50,110 @@ std::string XMLMetadataSupplier::GetResourceFile() const
return m_FileName; 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 if (psNode->eType == CXT_Text)
{ {
char ** todo; papszList = CSLAddNameValue(papszList, pszName, psNode->pszValue);
return todo; // TODO }
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;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment