27  const QDomElement metadataElem = document.firstChildElement( QStringLiteral( 
"metadata" ) );
 
   29  const QDomElement esri = metadataElem.firstChildElement( QStringLiteral( 
"Esri" ) );
 
   30  const QDomElement dataProperties = esri.firstChildElement( QStringLiteral( 
"DataProperties" ) );
 
   31  const QDomElement itemProps = dataProperties.firstChildElement( QStringLiteral( 
"itemProps" ) );
 
   32  metadata.
setIdentifier( itemProps.firstChildElement( QStringLiteral( 
"itemName" ) ).text() );
 
   34  const QDomElement dataIdInfo = metadataElem.firstChildElement( QStringLiteral( 
"dataIdInfo" ) );
 
   35  const QDomElement idInfo = metadataElem.firstChildElement( QStringLiteral( 
"idinfo" ) );
 
   38  const QDomElement idCitation = dataIdInfo.firstChildElement( QStringLiteral( 
"idCitation" ) );
 
   39  const QString title = idCitation.firstChildElement( QStringLiteral( 
"resTitle" ) ).text();
 
   43  if ( metadata.
identifier().isEmpty()  && !title.isEmpty() )
 
   46  const QDomElement citationDatesElement = idCitation.firstChildElement( QStringLiteral( 
"date" ) ).toElement();
 
   47  if ( !citationDatesElement.isNull() )
 
   50      const QDomElement createDateElement = citationDatesElement.firstChildElement( QStringLiteral( 
"createDate" ) ).toElement();
 
   51      if ( !createDateElement.isNull() )
 
   57      const QDomElement pubDateElement = citationDatesElement.firstChildElement( QStringLiteral( 
"pubDate" ) ).toElement();
 
   58      if ( !pubDateElement.isNull() )
 
   64      const QDomElement reviseDateElement = citationDatesElement.firstChildElement( QStringLiteral( 
"reviseDate" ) ).toElement();
 
   65      if ( !reviseDateElement.isNull() )
 
   71      const QDomElement supersededDateElement = citationDatesElement.firstChildElement( QStringLiteral( 
"supersDate" ) ).toElement();
 
   72      if ( !supersededDateElement.isNull() )
 
   80  const QDomElement idAbs = dataIdInfo.firstChildElement( QStringLiteral( 
"idAbs" ) );
 
   81  const QString abstractPlainText = QTextDocumentFragment::fromHtml( idAbs.text() ).toPlainText();
 
   85  const QDomElement idPurp = dataIdInfo.firstChildElement( QStringLiteral( 
"idPurp" ) );
 
   86  const QString purposePlainText = QTextDocumentFragment::fromHtml( idPurp.text() ).toPlainText();
 
   87  if ( !metadata.
abstract().isEmpty() )
 
   93  const QDomElement descript = idInfo.firstChildElement( QStringLiteral( 
"descript" ) );
 
   94  if ( !descript.isNull() )
 
   96    const QDomElement abstract = descript.firstChildElement( QStringLiteral( 
"abstract" ) );
 
   97    const QString abstractPlainText = QTextDocumentFragment::fromHtml( abstract.text() ).toPlainText();
 
   98    if ( !abstractPlainText.isEmpty() )
 
  100      if ( !metadata.
abstract().isEmpty() )
 
  101        metadata.
setAbstract( metadata.
abstract() + QStringLiteral( 
"\n\n" ) + abstractPlainText );
 
  106    const QDomElement purpose = descript.firstChildElement( QStringLiteral( 
"purpose" ) );
 
  107    const QString purposePlainText = QTextDocumentFragment::fromHtml( purpose.text() ).toPlainText();
 
  108    if ( !purposePlainText.isEmpty() )
 
  110      if ( !metadata.
abstract().isEmpty() )
 
  116    const QDomElement supplinf = descript.firstChildElement( QStringLiteral( 
"supplinf" ) );
 
  117    const QString supplinfPlainText = QTextDocumentFragment::fromHtml( supplinf.text() ).toPlainText();
 
  118    if ( !supplinfPlainText.isEmpty() )
 
  120      if ( !metadata.
abstract().isEmpty() )
 
  121        metadata.
setAbstract( metadata.
abstract() + QStringLiteral( 
"\n\n" ) + supplinfPlainText );
 
  128  const QDomElement suppInfo = dataIdInfo.firstChildElement( QStringLiteral( 
"suppInfo" ) );
 
  129  const QString suppInfoPlainText = QTextDocumentFragment::fromHtml( suppInfo.text() ).toPlainText();
 
  130  if ( !suppInfoPlainText.isEmpty() )
 
  132    if ( !metadata.
abstract().isEmpty() )
 
  133      metadata.
setAbstract( metadata.
abstract() + QStringLiteral( 
"\n\n" ) + suppInfoPlainText );
 
  139  const QDomElement dataLang = dataIdInfo.firstChildElement( QStringLiteral( 
"dataLang" ) );
 
  140  const QDomElement languageCode = dataLang.firstChildElement( QStringLiteral( 
"languageCode" ) );
 
  141  const QString language = languageCode.attribute( QStringLiteral( 
"value" ) ).toUpper();
 
  145  QDomElement searchKeys = dataIdInfo.firstChildElement( QStringLiteral( 
"searchKeys" ) );
 
  146  QStringList keywords;
 
  147  while ( !searchKeys.isNull() )
 
  149    QDomElement keyword = searchKeys.firstChildElement( QStringLiteral( 
"keyword" ) );
 
  150    while ( !keyword.isNull() )
 
  152      keywords << keyword.text();
 
  153      keyword = keyword.nextSiblingElement( QStringLiteral( 
"keyword" ) );
 
  156    searchKeys = searchKeys.nextSiblingElement( QStringLiteral( 
"searchKeys" ) );
 
  160  QDomElement themeKeys = dataIdInfo.firstChildElement( QStringLiteral( 
"themeKeys" ) );
 
  161  QStringList categories;
 
  162  while ( !themeKeys.isNull() )
 
  164    const QDomElement thesaName = themeKeys.firstChildElement( QStringLiteral( 
"thesaName" ) );
 
  165    const QString thesaTitle = thesaName.firstChildElement( QStringLiteral( 
"resTitle" ) ).text();
 
  167    const bool isSearchKeyWord = thesaTitle.compare( QLatin1String( 
"Common Search Terms" ), Qt::CaseInsensitive ) == 0;
 
  169    QDomElement themeKeyword = themeKeys.firstChildElement( QStringLiteral( 
"keyword" ) );
 
  170    while ( !themeKeyword.isNull() )
 
  172      if ( isSearchKeyWord )
 
  174        keywords.append( themeKeyword.text().split( 
',' ) );
 
  178        categories << themeKeyword.text();
 
  180      themeKeyword = themeKeyword.nextSiblingElement( QStringLiteral( 
"keyword" ) );
 
  182    themeKeys = themeKeys.nextSiblingElement( QStringLiteral( 
"themeKeys" ) );
 
  186  QDomElement keywordsElem = idInfo.firstChildElement( QStringLiteral( 
"keywords" ) );
 
  187  while ( !keywordsElem.isNull() )
 
  189    QDomElement theme = keywordsElem.firstChildElement( QStringLiteral( 
"theme" ) );
 
  190    while ( !theme.isNull() )
 
  192      categories << theme.firstChildElement( QStringLiteral( 
"themekey" ) ).text();
 
  193      theme = theme.nextSiblingElement( QStringLiteral( 
"theme" ) );
 
  196    keywordsElem = keywordsElem.nextSiblingElement( QStringLiteral( 
"keywords" ) );
 
  199  if ( !categories.isEmpty() )
 
  202  if ( !keywords.empty() )
 
  203    metadata.
addKeywords( QObject::tr( 
"Search keys" ), keywords );
 
  208  const QDomElement date = idCitation.firstChildElement( QStringLiteral( 
"date" ) );
 
  209  const QString pubDate = date.firstChildElement( QStringLiteral( 
"pubDate" ) ).text();
 
  210  const QDateTime publicationDate = QDateTime::fromString( pubDate, Qt::ISODate );
 
  211  if ( publicationDate.isValid() )
 
  218    QDomElement timeperd = idInfo.firstChildElement( QStringLiteral( 
"timeperd" ) );
 
  219    while ( !timeperd.isNull() )
 
  221      if ( timeperd.firstChildElement( QStringLiteral( 
"current" ) ).text().compare( QLatin1String( 
"publication date" ) ) == 0 )
 
  223        const QDomElement timeinfo = timeperd.firstChildElement( QStringLiteral( 
"timeinfo" ) );
 
  224        const QDomElement sngdate = timeinfo.firstChildElement( QStringLiteral( 
"sngdate" ) );
 
  225        if ( !sngdate.isNull() )
 
  227          const QDomElement caldate = sngdate.firstChildElement( QStringLiteral( 
"caldate" ) );
 
  228          const QString caldateString = caldate.text();
 
  229          const QDateTime publicationDate = QDateTime::fromString( caldateString, QStringLiteral( 
"MMMM yyyy" ) );
 
  230          if ( publicationDate.isValid() )
 
  236        const QDomElement rngdates = timeinfo.firstChildElement( QStringLiteral( 
"rngdates" ) );
 
  237        if ( !rngdates.isNull() )
 
  239          const QDomElement begdate = rngdates.firstChildElement( QStringLiteral( 
"begdate" ) );
 
  240          const QDomElement enddate = rngdates.firstChildElement( QStringLiteral( 
"enddate" ) );
 
  241          const QString begdateString = begdate.text();
 
  242          const QString enddateString = enddate.text();
 
  245          for ( 
const QString format : { 
"yyyy-MM-dd", 
"dd/MM/yyyy" } )
 
  247            if ( !begin.isValid() )
 
  248              begin = QDateTime::fromString( begdateString, format );
 
  249            if ( !end.isValid() )
 
  250              end = QDateTime::fromString( enddateString, format );
 
  253          if ( begin.isValid() || end.isValid() )
 
  261      timeperd = timeperd.nextSiblingElement( QStringLiteral( 
"timeperd" ) );
 
  267  QDomElement refSysInfo = metadataElem.firstChildElement( QStringLiteral( 
"refSysInfo" ) );
 
  268  while ( !refSysInfo.isNull() )
 
  270    const QDomElement refSystem = refSysInfo.firstChildElement( QStringLiteral( 
"RefSystem" ) );
 
  271    const QDomElement refSysID = refSystem.firstChildElement( QStringLiteral( 
"refSysID" ) );
 
  272    const QDomElement identAuth = refSysID.firstChildElement( QStringLiteral( 
"identAuth" ) );
 
  273    if ( !identAuth.isNull() )
 
  275      if ( identAuth.firstChildElement( QStringLiteral( 
"resTitle" ) ).text().compare( QLatin1String( 
"EPSG Geodetic Parameter Dataset" ) ) == 0 )
 
  277        const QString code = refSysID.firstChildElement( QStringLiteral( 
"identCode" ) ).attribute( QStringLiteral( 
"code" ) );
 
  283      const QString code = refSysID.firstChildElement( QStringLiteral( 
"identCode" ) ).attribute( QStringLiteral( 
"code" ) );
 
  284      const QString auth = refSysID.firstChildElement( QStringLiteral( 
"idCodeSpace" ) ).text();
 
  293    refSysInfo = refSysInfo.nextSiblingElement( QStringLiteral( 
"refSysInfo" ) );
 
  297  QDomElement dataExt = dataIdInfo.firstChildElement( QStringLiteral( 
"dataExt" ) );
 
  298  while ( !dataExt.isNull() )
 
  300    const QDomElement geoEle = dataExt.firstChildElement( QStringLiteral( 
"geoEle" ) );
 
  301    if ( !geoEle.isNull() )
 
  303      const QDomElement geoBndBox = geoEle.firstChildElement( QStringLiteral( 
"GeoBndBox" ) );
 
  304      const double west = geoBndBox.firstChildElement( QStringLiteral( 
"westBL" ) ).text().toDouble();
 
  305      const double east = geoBndBox.firstChildElement( QStringLiteral( 
"eastBL" ) ).text().toDouble();
 
  306      const double south = geoBndBox.firstChildElement( QStringLiteral( 
"northBL" ) ).text().toDouble();
 
  307      const double north = geoBndBox.firstChildElement( QStringLiteral( 
"southBL" ) ).text().toDouble();
 
  311      spatialExtent.
bounds = 
QgsBox3D( west, south, 0, east, north, 0 );
 
  316    dataExt = dataExt.nextSiblingElement( QStringLiteral( 
"dataExt" ) );
 
  322  QStringList licenses;
 
  325  QDomElement resConst = dataIdInfo.firstChildElement( QStringLiteral( 
"resConst" ) );
 
  326  while ( !resConst.isNull() )
 
  328    QDomElement legConsts = resConst.firstChildElement( QStringLiteral( 
"LegConsts" ) );
 
  329    while ( !legConsts.isNull() )
 
  331      const QString restrictCd = legConsts.firstChildElement( QStringLiteral( 
"useConsts" ) ).firstChildElement( QStringLiteral( 
"RestrictCd" ) ).attribute( QStringLiteral( 
"value" ) );
 
  333      if ( restrictCd.compare( QLatin1String( 
"005" ) ) == 0 )
 
  335        licenses << QTextDocumentFragment::fromHtml( legConsts.firstChildElement( QStringLiteral( 
"useLimit" ) ).text() ).toPlainText();
 
  337      else if ( restrictCd.compare( QLatin1String( 
"006" ) ) == 0 )
 
  339        rights << QTextDocumentFragment::fromHtml( legConsts.firstChildElement( QStringLiteral( 
"useLimit" ) ).text() ).toPlainText();
 
  341      legConsts = legConsts.nextSiblingElement( QStringLiteral( 
"LegConsts" ) );
 
  344    QDomElement secConsts = resConst.firstChildElement( QStringLiteral( 
"SecConsts" ) );
 
  345    while ( !secConsts.isNull() )
 
  348      constraint.
type = QObject::tr( 
"Security constraints" );
 
  349      constraint.
constraint = QTextDocumentFragment::fromHtml( secConsts.firstChildElement( QStringLiteral( 
"userNote" ) ).text() ).toPlainText();
 
  350      constraints << constraint;
 
  351      secConsts = secConsts.nextSiblingElement( QStringLiteral( 
"SecConsts" ) );
 
  354    QDomElement consts = resConst.firstChildElement( QStringLiteral( 
"Consts" ) );
 
  355    while ( !consts.isNull() )
 
  358      constraint.
type = QObject::tr( 
"Limitations of use" );
 
  359      constraint.
constraint = QTextDocumentFragment::fromHtml( consts.firstChildElement( QStringLiteral( 
"useLimit" ) ).text() ).toPlainText();
 
  360      constraints << constraint;
 
  361      consts = consts.nextSiblingElement( QStringLiteral( 
"Consts" ) );
 
  364    resConst = resConst.nextSiblingElement( QStringLiteral( 
"resConst" ) );
 
  367  const QDomElement idCredit = dataIdInfo.firstChildElement( QStringLiteral( 
"idCredit" ) );
 
  368  const QString credit = idCredit.text();
 
  369  if ( !credit.isEmpty() )
 
  373  QDomElement accconst = idInfo.firstChildElement( QStringLiteral( 
"accconst" ) );
 
  374  while ( !accconst.isNull() )
 
  377    constraint.
type = QObject::tr( 
"Access" );
 
  378    constraint.
constraint = QTextDocumentFragment::fromHtml( accconst.text() ).toPlainText();
 
  379    constraints << constraint;
 
  381    accconst = accconst.nextSiblingElement( QStringLiteral( 
"accconst" ) );
 
  383  QDomElement useconst = idInfo.firstChildElement( QStringLiteral( 
"useconst" ) );
 
  384  while ( !useconst.isNull() )
 
  386    rights << QTextDocumentFragment::fromHtml( useconst.text() ).toPlainText();
 
  387    useconst = useconst.nextSiblingElement( QStringLiteral( 
"useconst" ) );
 
  395  const QDomElement distInfo = metadataElem.firstChildElement( QStringLiteral( 
"distInfo" ) );
 
  396  const QDomElement distributor = distInfo.firstChildElement( QStringLiteral( 
"distributor" ) );
 
  398  QDomElement distorTran = distributor.firstChildElement( QStringLiteral( 
"distorTran" ) );
 
  399  while ( !distorTran.isNull() )
 
  401    const QDomElement onLineSrc = distorTran.firstChildElement( QStringLiteral( 
"onLineSrc" ) );
 
  402    if ( !onLineSrc.isNull() )
 
  405      link.
url = onLineSrc.firstChildElement( QStringLiteral( 
"linkage" ) ).text();
 
  407      const QDomElement distorFormat = distributor.firstChildElement( QStringLiteral( 
"distorFormat" ) );
 
  408      link.
name = distorFormat.firstChildElement( QStringLiteral( 
"formatName" ) ).text();
 
  409      link.
type = distorFormat.firstChildElement( QStringLiteral( 
"formatSpec" ) ).text();
 
  411      if ( link.
type.isEmpty() )
 
  414        link.
type = onLineSrc.firstChildElement( QStringLiteral( 
"protocol" ) ).text();
 
  419    distorTran = distorTran.nextSiblingElement( QStringLiteral( 
"distorTran" ) );
 
  423  const QDomElement dqInfo = metadataElem.firstChildElement( QStringLiteral( 
"dqInfo" ) );
 
  424  const QDomElement dataLineage = dqInfo.firstChildElement( QStringLiteral( 
"dataLineage" ) );
 
  425  const QString statement = QTextDocumentFragment::fromHtml( dataLineage.firstChildElement( QStringLiteral( 
"statement" ) ).text() ).toPlainText();
 
  426  if ( !statement.isEmpty() )
 
  429  QDomElement dataSource = dataLineage.firstChildElement( QStringLiteral( 
"dataSource" ) );
 
  430  while ( !dataSource.isNull() )
 
  432    metadata.
addHistoryItem( QObject::tr( 
"Data source: %1" ).arg( QTextDocumentFragment::fromHtml( dataSource.firstChildElement( QStringLiteral( 
"srcDesc" ) ).text() ).toPlainText() ) );
 
  433    dataSource = dataSource.nextSiblingElement( QStringLiteral( 
"dataSource" ) );
 
  437  const QDomElement mdContact = metadataElem.firstChildElement( QStringLiteral( 
"mdContact" ) );
 
  438  if ( !mdContact.isNull() )
 
  441    contact.
name = mdContact.firstChildElement( QStringLiteral( 
"rpIndName" ) ).text();
 
  442    contact.
organization = mdContact.firstChildElement( QStringLiteral( 
"rpOrgName" ) ).text();
 
  443    contact.
position = mdContact.firstChildElement( QStringLiteral( 
"rpPosName" ) ).text();
 
  445    const QString role = mdContact.firstChildElement( QStringLiteral( 
"role" ) ).firstChildElement( QStringLiteral( 
"RoleCd" ) ).attribute( QStringLiteral( 
"value" ) );
 
  446    if ( role == QLatin1String( 
"007" ) )
 
  447      contact.
role = QObject::tr( 
"Point of contact" );
 
  449    const QDomElement rpCntInfo = mdContact.firstChildElement( QStringLiteral( 
"rpCntInfo" ) );
 
  450    contact.
email = rpCntInfo.firstChildElement( QStringLiteral( 
"cntAddress" ) ).firstChildElement( QStringLiteral( 
"eMailAdd" ) ).text();
 
  451    contact.
voice = rpCntInfo.firstChildElement( QStringLiteral( 
"cntPhone" ) ).firstChildElement( QStringLiteral( 
"voiceNum" ) ).text();
 
  453    QDomElement cntAddress = rpCntInfo.firstChildElement( QStringLiteral( 
"cntAddress" ) );
 
  454    while ( !cntAddress.isNull() )
 
  458      address.
type = cntAddress.attribute( QStringLiteral( 
"addressType" ) );
 
  459      address.
address = cntAddress.firstChildElement( QStringLiteral( 
"delPoint" ) ).text();
 
  460      address.
city = cntAddress.firstChildElement( QStringLiteral( 
"city" ) ).text();
 
  461      address.
administrativeArea = cntAddress.firstChildElement( QStringLiteral( 
"adminArea" ) ).text();
 
  462      address.
postalCode = cntAddress.firstChildElement( QStringLiteral( 
"postCode" ) ).text();
 
  463      address.
country = cntAddress.firstChildElement( QStringLiteral( 
"country" ) ).text();
 
  467      cntAddress = cntAddress.nextSiblingElement( QStringLiteral( 
"cntAddress" ) );
 
  475  const QDomElement ptcontac = idInfo.firstChildElement( QStringLiteral( 
"ptcontac" ) );
 
  476  const QDomElement cntinfo = ptcontac.firstChildElement( QStringLiteral( 
"cntinfo" ) );
 
  477  if ( !cntinfo.isNull() )
 
  480    const QDomElement cntorgp = cntinfo.firstChildElement( QStringLiteral( 
"cntorgp" ) );
 
  481    const QString org = cntorgp.firstChildElement( QStringLiteral( 
"cntorg" ) ).text();
 
  485    contact.
role = QObject::tr( 
"Point of contact" );
 
  487    const QDomElement rpCntInfo = mdContact.firstChildElement( QStringLiteral( 
"rpCntInfo" ) );
 
  488    contact.
email = cntinfo.firstChildElement( QStringLiteral( 
"cntemail" ) ).text();
 
  489    contact.
fax = cntinfo.firstChildElement( QStringLiteral( 
"cntfax" ) ).text();
 
  490    contact.
voice = cntinfo.firstChildElement( QStringLiteral( 
"cntvoice" ) ).text();
 
  492    QDomElement cntaddr = cntinfo.firstChildElement( QStringLiteral( 
"cntaddr" ) );
 
  493    while ( !cntaddr.isNull() )
 
  497      QDomElement addressElem = cntaddr.firstChildElement( QStringLiteral( 
"address" ) );
 
  498      while ( !addressElem.isNull() )
 
  500        const QString addressPart = addressElem.text();
 
  502        addressElem = addressElem.nextSiblingElement( QStringLiteral( 
"address" ) );
 
  504      address.
type = cntaddr.firstChildElement( QStringLiteral( 
"addrtype" ) ).text();
 
  505      address.
city = cntaddr.firstChildElement( QStringLiteral( 
"city" ) ).text();
 
  506      address.
administrativeArea = cntaddr.firstChildElement( QStringLiteral( 
"state" ) ).text();
 
  507      address.
postalCode = cntaddr.firstChildElement( QStringLiteral( 
"postal" ) ).text();
 
  508      address.
country = cntaddr.firstChildElement( QStringLiteral( 
"country" ) ).text();
 
  512      cntaddr = cntaddr.nextSiblingElement( QStringLiteral( 
"cntaddr" ) );