LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gml - parsexsd.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 79 59 74.7 %
Date: 2010-01-09 Functions: 2 2 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: parsexsd.cpp 17629 2009-09-10 14:51:45Z chaitanya $
       3                 :  *
       4                 :  * Project:  GML Reader
       5                 :  * Purpose:  Implementation of GMLReader::ParseXSD() method.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2005, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  * 
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  * 
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      22                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gmlreader.h"
      31                 : #include "cpl_error.h"
      32                 : 
      33                 : #if HAVE_XERCES != 0 || defined(HAVE_EXPAT)
      34                 : 
      35                 : #include "gmlreaderp.h"
      36                 : #include "cpl_conv.h"
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                              StripNS()                               */
      40                 : /*                                                                      */
      41                 : /*      Return potentially shortened form of string with namespace      */
      42                 : /*      stripped off if there is one.  Returns pointer into             */
      43                 : /*      original string.                                                */
      44                 : /************************************************************************/
      45                 : 
      46              15 : const char *StripNS( const char *pszFullValue )
      47                 : 
      48                 : {
      49              15 :     const char *pszColon = strstr( pszFullValue, ":" );
      50              15 :     if( pszColon == NULL )
      51               0 :         return pszFullValue;
      52                 :     else
      53              15 :         return pszColon + 1;
      54                 : }
      55                 : 
      56                 : /************************************************************************/
      57                 : /*                              ParseXSD()                              */
      58                 : /************************************************************************/
      59                 : 
      60               3 : int GMLReader::ParseXSD( const char *pszFile )
      61                 : 
      62                 : {
      63               3 :     if( pszFile == NULL )
      64               0 :         return FALSE;
      65                 : 
      66                 : /* -------------------------------------------------------------------- */
      67                 : /*      Load the raw XML file.                                          */
      68                 : /* -------------------------------------------------------------------- */
      69               3 :     CPLXMLNode *psXSDTree = CPLParseXMLFile( pszFile );
      70                 :     
      71               3 :     if( psXSDTree == NULL )
      72               0 :         return FALSE;
      73                 : 
      74                 : /* -------------------------------------------------------------------- */
      75                 : /*      Strip off any namespace qualifiers.                             */
      76                 : /* -------------------------------------------------------------------- */
      77               3 :     CPLStripXMLNamespace( psXSDTree, NULL, TRUE );
      78                 : 
      79                 : /* -------------------------------------------------------------------- */
      80                 : /*      Find <schema> root element.                                     */
      81                 : /* -------------------------------------------------------------------- */
      82               3 :     CPLXMLNode *psSchemaNode = CPLGetXMLNode( psXSDTree, "=schema" );
      83               3 :     if( psSchemaNode == NULL )
      84                 :     {
      85               0 :         CPLDestroyXMLNode( psXSDTree );
      86               0 :         return FALSE;
      87                 :     }
      88                 : 
      89                 : /* ==================================================================== */
      90                 : /*      Process each feature class definition.                          */
      91                 : /* ==================================================================== */
      92                 :     CPLXMLNode *psThis;
      93               3 :     int         bIsLevel0 = TRUE;
      94                 : 
      95              33 :     for( psThis = psSchemaNode->psChild; 
      96                 :          psThis != NULL; psThis = psThis->psNext )
      97                 :     {
      98                 : /* -------------------------------------------------------------------- */
      99                 : /*      Check for <xs:element> node.                                    */
     100                 : /* -------------------------------------------------------------------- */
     101              30 :         if( psThis->eType != CXT_Element 
     102                 :             || !EQUAL(psThis->pszValue,"element") )
     103              24 :             continue;
     104                 : 
     105                 : /* -------------------------------------------------------------------- */
     106                 : /*      Check the substitution group.                                   */
     107                 : /* -------------------------------------------------------------------- */
     108                 :         const char *pszSubGroup = 
     109               6 :             StripNS(CPLGetXMLValue(psThis,"substitutionGroup",""));
     110                 : 
     111                 :         // Old OGR produced elements for the feature collection.
     112               6 :         if( EQUAL(pszSubGroup, "_FeatureCollection") )
     113               3 :             continue;
     114                 : 
     115               3 :         if( !EQUAL(pszSubGroup, "_Feature") )
     116                 :         {
     117               0 :             bIsLevel0 = FALSE;
     118               0 :             break;
     119                 :         }
     120                 :         
     121                 : /* -------------------------------------------------------------------- */
     122                 : /*      Get name                                                        */
     123                 : /* -------------------------------------------------------------------- */
     124                 :         const char *pszName;
     125                 : 
     126               3 :         pszName = CPLGetXMLValue( psThis, "name", NULL );
     127               3 :         if( pszName == NULL )
     128                 :         {
     129               0 :             bIsLevel0 = FALSE;
     130               0 :             break;
     131                 :         }
     132                 : 
     133                 : /* -------------------------------------------------------------------- */
     134                 : /*      Get type and verify relationship with name.                     */
     135                 : /* -------------------------------------------------------------------- */
     136                 :         const char *pszType;
     137                 : 
     138               3 :         pszType = CPLGetXMLValue( psThis, "type", NULL );
     139               3 :         if( strstr( pszType, ":" ) != NULL )
     140               3 :             pszType = strstr( pszType, ":" ) + 1; 
     141               3 :         if( pszType == NULL || !EQUALN(pszType,pszName,strlen(pszName)) 
     142                 :             || !(EQUAL(pszType+strlen(pszName),"_Type") ||
     143                 :                     EQUAL(pszType+strlen(pszName),"Type")) )
     144                 :         {
     145               0 :             bIsLevel0 = FALSE;
     146               0 :             break;
     147                 :         }
     148                 : 
     149                 : /* -------------------------------------------------------------------- */
     150                 : /*      The very next element should be the corresponding               */
     151                 : /*      complexType declaration for the element.                        */
     152                 : /* -------------------------------------------------------------------- */
     153               3 :         psThis = psThis->psNext;
     154               6 :         while( psThis != NULL && psThis->eType == CXT_Comment )
     155               0 :             psThis = psThis->psNext;
     156                 : 
     157               3 :         if( psThis == NULL 
     158                 :             || psThis->eType != CXT_Element
     159                 :             || !EQUAL(psThis->pszValue,"complexType") 
     160                 :             || !EQUAL(CPLGetXMLValue(psThis,"name",""),pszType) )
     161                 :         {
     162               0 :             bIsLevel0 = FALSE;
     163               0 :             break;
     164                 :         }
     165                 : 
     166                 : /* -------------------------------------------------------------------- */
     167                 : /*      Grab the sequence of extensions greatgrandchild.                */
     168                 : /* -------------------------------------------------------------------- */
     169                 :         CPLXMLNode *psAttrSeq = 
     170                 :             CPLGetXMLNode( psThis, 
     171               3 :                            "complexContent.extension.sequence" );
     172                 : 
     173               3 :         if( psAttrSeq == NULL )
     174                 :         {
     175               0 :             bIsLevel0 = FALSE;
     176               0 :             break;
     177                 :         }
     178                 : 
     179                 : /* -------------------------------------------------------------------- */
     180                 : /*      We are pretty sure this going to be a valid Feature class       */
     181                 : /*      now, so create it.                                              */
     182                 : /* -------------------------------------------------------------------- */
     183               3 :         GMLFeatureClass *poClass = new GMLFeatureClass( pszName );
     184                 : 
     185                 : /* -------------------------------------------------------------------- */
     186                 : /*      Loop over each of the attribute elements being defined for      */
     187                 : /*      this feature class.                                             */
     188                 : /* -------------------------------------------------------------------- */
     189                 :         CPLXMLNode *psAttrDef;
     190                 : 
     191              15 :         for( psAttrDef = psAttrSeq->psChild; 
     192                 :              psAttrDef != NULL; 
     193                 :              psAttrDef = psAttrDef->psNext )
     194                 :         {
     195              12 :             if( !EQUAL(psAttrDef->pszValue,"element") )
     196               0 :                 continue;
     197                 : 
     198                 :             // For now we skip geometries .. fixup later.
     199              12 :             if( CPLGetXMLNode( psAttrDef, "simpleType" ) == NULL )
     200               3 :                 continue;
     201                 : 
     202                 :             GMLPropertyDefn *poProp = new GMLPropertyDefn( 
     203                 :                 CPLGetXMLValue( psAttrDef, "name", "unnamed" ),
     204               9 :                 CPLGetXMLValue( psAttrDef, "name", "unnamed" ) );
     205                 : 
     206                 :             const char *pszBase = 
     207                 :                 StripNS( CPLGetXMLValue( psAttrDef, 
     208               9 :                                          "simpleType.restriction.base", "" ));
     209                 : 
     210               9 :             if( EQUAL(pszBase,"decimal") )
     211                 :             {
     212               3 :                 poProp->SetType( GMLPT_Real );
     213                 :                 const char *pszWidth = 
     214                 :                     CPLGetXMLValue( psAttrDef, 
     215               3 :                               "simpleType.restriction.totalDigits.value", "0" );
     216                 :                 const char *pszPrecision = 
     217                 :                     CPLGetXMLValue( psAttrDef, 
     218               3 :                               "simpleType.restriction.fractionDigits.value", "0" );
     219               3 :                 poProp->SetWidth( atoi(pszWidth) );
     220               3 :                 poProp->SetPrecision( atoi(pszPrecision) );
     221                 :             }
     222                 :             
     223               6 :             else if( EQUAL(pszBase,"float") 
     224                 :                      || EQUAL(pszBase,"double") )
     225               0 :                 poProp->SetType( GMLPT_Real );
     226                 : 
     227               6 :             else if( EQUAL(pszBase,"integer") )
     228                 :             {
     229               2 :                 poProp->SetType( GMLPT_Integer );
     230                 :                 const char *pszWidth = 
     231                 :                     CPLGetXMLValue( psAttrDef, 
     232               2 :                               "simpleType.restriction.totalDigits.value", "0" );
     233               2 :                 poProp->SetWidth( atoi(pszWidth) );
     234                 :             }
     235                 : 
     236               4 :             else if( EQUAL(pszBase,"string") )
     237                 :             {
     238               4 :                 poProp->SetType( GMLPT_String );
     239                 :                 const char *pszWidth = 
     240                 :                     CPLGetXMLValue( psAttrDef, 
     241               4 :                               "simpleType.restriction.maxLength.value", "0" );
     242               4 :                 poProp->SetWidth( atoi(pszWidth) );
     243                 :             }
     244                 : 
     245                 :             else
     246               0 :                 poProp->SetType( GMLPT_Untyped );
     247                 : 
     248               9 :             poClass->AddProperty( poProp );
     249                 :         }
     250                 : 
     251                 : /* -------------------------------------------------------------------- */
     252                 : /*      Class complete, add to reader class list.                       */
     253                 : /* -------------------------------------------------------------------- */
     254               3 :         poClass->SetSchemaLocked( TRUE );
     255                 : 
     256               3 :         AddClass( poClass );
     257                 :     }
     258                 : 
     259               3 :     CPLDestroyXMLNode( psXSDTree );
     260                 : 
     261               3 :     if( m_nClassCount > 0 )
     262                 :     {
     263               3 :         SetClassListLocked( TRUE );
     264               3 :         return TRUE;
     265                 :     }
     266                 :     else
     267               0 :         return FALSE;
     268                 : }
     269                 : 
     270                 : #endif /* HAVE_XERCES == 1  || defined(HAVE_EXPAT) */
     271                 : 

Generated by: LCOV version 1.7