Select to view content in your preferred language

error with parse xml

2205
5
12-28-2021 12:00 AM
danielROUFFART1
Emerging Contributor

Hi,

i work on a python program for changing attribute in a xml. but when i  test my script i've got a message who say :

 ---------------------------------------------------------------------------

SyntaxError Traceback (most recent call last) File C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\ast.py, in parse: Line 35: return compile(source, filename, mode, PyCF_ONLY_AST) SyntaxError: invalid syntax (<string>, line 11)

---------------------------------------------------------------------------

 

 

---------------------------------------------------------------------------
SyntaxError                               Traceback (most recent call last)
File C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\ast.py, in parse:
Line 35:    return compile(source, filename, mode, PyCF_ONLY_AST)

SyntaxError: invalid syntax (<string>, line 11)
---------------------------------------------------------------------------

 

 

 

 

can you help me to fix the problem please?

 

 

 

 

import os
import sys
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element

import arcpy
from arcpy import metadata as md
from datetime import datetime

# Script arguments...
Source_Metadata = [
    arcpy.GetParameterAsText(0)]

# Local variables
#    new purpose text
resTitle1 = "n/a"
jason = "PMMCU"
jemets = "GEMET - INSPIRE themes, version 1.0"
madate = "2021-11-15T00:00:00"
madate2 = "2010-12-08T00:00:00"
opendatanorme = "CC0, CC BY, CC BY-SA"
Pub = "publication"
Al = "GeoService"
reglement = "Selon reglèment"
commission = "Commission Regulation (EU) No 1089/2010 of 23 November 2010 implementing Directive 2007/2/EC of the European Parliament and of the Council as regards interoperability of spatial data sets and services"
conpass = "1"
domaine = "DQDomConsis"
balise = r'dqInfo/report'
att = "dimension"
valAtt = "horizontal"
type = "type"
newtype = "DQDomConsis"
balise2 = r'dqInfo/report/EvalMethTypeCd'
att2 = "value"
valAtt2 = "001"
balise3 = r'dqInfo/ScopeCD'
att3 = "value"
valAtt3 = "005"
########################################################################################

# fonction ppour mettre à jour des valeurs
def update_metadata(root):
    num_elements = 0
    # Recherche de la balise depuis root
    beta = root.find(".//" + balise)
    if beta is not None:
        print ('Les attributs de la balise ' + balise + " sont : " + str(beta.attrib))
        if beta.get(type) is not None:
            # L'attribut recherché existe
            print ("L'attribut recherché existe (" + type + ")")
            print ("Valeur actuelle : " + beta.get(type))
            print ("Nouvelle valeur : " + newtype)
            beta.set(type, newtype)
            num_elements += 1
        if beta.get(type) is None:
            # L'attribut recherché n'existe pas
            print ("L'attribut recherché n'existe pas (" + type + ")")
            print ("Ajout de cet attribut avec la valeur : " + newtype)
            beta.set(type, newtype)
            num_elements += 1
    else:
        print("La balise n'existe pas")

    return num_elements

    num_elements = 0
    # Recherche de la balise depuis root
    zeta = root.find(".//" + balise2)
    # balise de ressource quality report dimension
    if zeta is not None:
        # Affichage des attributs de la balise
        print ('Les attributs de la balise ' + balise2 + " sont : " + str(zeta.attrib))
        if zeta.get(att2) is not None:
            # L'attribut recherché existe
            print ("L'attribut recherché existe (" + att2 + ")")
            print ("Valeur actuelle : " + zeta.get(att2))
            print ("Nouvelle valeur : " + valAtt2)
            zeta.set(att2, valAtt2)
            num_elements += 1
        if zeta.get(att2) is None:
            # L'attribut recherché n'existe pas
            print ("L'attribut recherché n'existe pas (" + att2 + ")")
            print ("Ajout de cet attribut avec la valeur : " + valAtt2)
            zeta.set(att2, valAtt2)
            num_elements += 1
    else:
        print("La balise n'existe pas")
    return num_elements


def update_metadata(root):
    # Recherche de la balise depuis root
    geta = root.find(".//" + balise3)
    # balise de ressource quality report dimension
    if geta is not None:
        # Affichage des attributs de la balise
        print ('Les attributs de la balise ' + balise3 + " sont : " + str(zeta.attrib))
        if geta.get(att3) is not None:
            # L'attribut recherché existe
            print ("L'attribut recherché existe (" + att3 + ")")
            print ("Valeur actuelle : " + zeta.get(att3))
            print ("Nouvelle valeur : " + valAtt3)
            geta.set(att3, valAtt3)
            num_elements += 1
        if geta.get(att3) is None:
            # L'attribut recherché n'existe pas
            print ("L'attribut recherché n'existe pas (" + att3 + ")")
            print ("Ajout de cet attribut avec la valeur : " + valAtt3)
            geta.set(att3, valAtt3)
            num_elements += 1
    else:
        print("La balise n'existe pas")
    return num_elements



# get and save item metadata
for item in Source_Metadata:
    arcpy.AddMessage("Item: {0}".format(item))

    # get the item's metadata xml
    item_md = md.Metadata(item)
    metadata_xml_string = item_md.xml

    # create an ElementTree object from the metadata XML string
    root = ET.fromstring(metadata_xml_string)

    # call the update_metadata function to modify the item's metadata
    changes = update_metadata(root)

    if changes > 0:
        # get modified XML
        updated_xml_string = ET.tostring(root, encoding="utf-8")

        # import result back into metadata
        arcpy.AddMessage("Saving updated metadata with the item...")
        item_md.xml = updated_xml_string
        item_md.save()
    else:
        arcpy.AddMessage("No changes to save")

arcpy.AddMessage('Finished updating metadata for all source metadata items')


#######################################################################################

# function to update purpose and credits in metadata
def update_metadata(root):
    num_elements = 0
    for child in root:
        print(child.tag, child.attrib)
        # modify purpose element's text
        # there is only supposed to be one purpose element in metadata
        # replace purpose element text if element exists
        # if element doesn't exist, do nothing
    purposeEls = root.findall(".//formatVer")
    for element in purposeEls:
        if element.text is not None:
            element.text = resTitle1
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls1 = root.findall(".//idCredit")
    for element in purposeEls1:
        if element.text is not None:
            element.text = jason
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls2 = root.findall(".//useLimit")
    for element in purposeEls2:
        if element.text is not None:
            element.text = opendatanorme
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls2 = root.findall(".//identCode")
    for element in purposeEls2:
        if element.text is not None:
            element.text = Pub
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls2 = root.findall(".//formatName")
    for element in purposeEls2:
        if element.text is not None:
            element.text = Al
            num_elements += 1

        # add credits element to dataIdInfo parent, if the parent exists
        # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
        # ISO allows many idCredit elements, and many are supported in ArcGIS
        # append a new idCredit element with appropriate text, existing elements remain
    dataIdInfoEls = root.findall("./dataIdInfo")
    for element in dataIdInfoEls:
        if element:
            newCreditEl = ET.SubElement(element, "themeKeys")
            newCreditEl1 = ET.SubElement(newCreditEl, "thesaName")
            newCreditEl2 = ET.SubElement(newCreditEl1, "resTitle")
            newCreditEl2.text = jemets
            num_elements += 1

    # add credits element to dataIdInfo parent, if the parent exists
    # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
    # ISO allows many idCredit elements, and many are supported in ArcGIS
    # append a new idCredit element with appropriate text, existing elements remain
    dataIdInfoEls = root.findall("./dataIdInfo")
    for element in dataIdInfoEls:
        if element.text is not None:
            newCreditEl = ET.SubElement(element, "themeKeys")
            newCreditEl1 = ET.SubElement(newCreditEl, "thesaName")
            newCreditEl2 = ET.SubElement(newCreditEl1, "date")
            newCreditEl3 = ET.SubElement(newCreditEl1, "pubDate")
            newCreditEl3.time = madate
            num_elements += 1
    ################################################################################################
    # modif champ quality

    # add credits element to dataIdInfo parent, if the parent exists
    # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
    # ISO allows many idCredit elements, and many are supported in ArcGIS
    # append a new idCredit element with appropriate text, existing elements remain
    dataIdInfoEls1 = root.findall("./dqInfo")
    # for element in dataIdInfoEls1:
    #    if element.text is not None:
    #       newCreditcom = ET.SubElement(element, "report")
    #        newCreditcom1 = ET.SubElement(newCreditcom, "measResult")
    #        newCreditcom2 = ET.SubElement(newCreditcom1, "ConResult")
    #        newCreditcom3 = ET.SubElement(newCreditcom2, "conSpec")
    #        newCreditcom4 = ET.SubElement(newCreditcom3, "resTitle")
    #        newCreditcom4.text = commission
    #        num_elements += 1


    # add credits element to dataIdInfo parent, if the parent exists
    # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
    # ISO allows many idCredit elements, and many are supported in ArcGIS
    # append a new idCredit element with appropriate text, existing elements remain
    for element in dataIdInfoEls1:
        if element:
            newCreditreg = ET.SubElement(element, "report")
            newCreditreg1 = ET.SubElement(newCreditreg, "measResult")
            newCreditreg2 = ET.SubElement(newCreditreg1, "ConResult")
            newCreditreg3 = ET.SubElement(newCreditreg2, "conSpec")
            newCreditreg4 = ET.SubElement(newCreditreg3, "resAltTitle")
            newCredit4 = ET.SubElement(newCreditreg3, "collTitle")
            newCreditEll4 = ET.SubElement(newCreditreg3, "date")
            newCreditEll5 = ET.SubElement(newCreditEll4, "pubDate")
            newCreditcom4 = ET.SubElement(newCreditreg3, "resTitle")
            newPass4 = ET.SubElement(newCreditreg2, "conPass")  # type: Element

            newCreditcom4.text = commission
            newCreditreg4.text = reglement
            newCredit4.text = reglement
            newCreditEll5.text = madate2
            newPass4.text = conpass
            newCreditreg.text = domaine

            num_elements += 1


    return num_elements


# get and save item metadata
for item in Source_Metadata:
    arcpy.AddMessage("Item: {0}".format(item))

    # get the item's metadata xml
    item_md = md.Metadata(item)
    metadata_xml_string = item_md.xml

    # create an ElementTree object from the metadata XML string
    root = ET.fromstring(metadata_xml_string)

    # call the update_metadata function to modify the item's metadata
    changes = update_metadata(root)

    if changes > 0:
        # get modified XML
        updated_xml_string = ET.tostring(root, encoding="utf-8")

        # import result back into metadata
        arcpy.AddMessage("Saving updated metadata with the item...")
        item_md.xml = updated_xml_string
        item_md.save()
    else:
        arcpy.AddMessage("No changes to save")

arcpy.AddMessage('Finished updating metadata for all source metadataA items')

 

 

 

thanks

0 Kudos
5 Replies
DanPatterson
MVP Esteemed Contributor

Source_Metadata = [
arcpy.GetParameterAsText(0)]

what is the parameter string's value? The error suggests it doesn't like it


... sort of retired...
0 Kudos
danielROUFFART1
Emerging Contributor

thank for your return

Source_Metadata = [
arcpy.GetParameterAsText(0)]

this parameter it the where he can found the datalayer.

for example we can write    Source_Metadata = [C:\Users\TOTO\AppData\Roaming\Esri\ArcGISPro\Favorites\tata.gdb]

 

0 Kudos
danielROUFFART1
Emerging Contributor

ok so  i found the problem and fix them:

now i want to change under-tag in xml tag so i use this script:

import os
import sys
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element

import arcpy
from arcpy import metadata as md
from datetime import datetime

# Script arguments...
Source_Metadata = [r'arcpy.GetParameterAsText(0)']

# Local variables
#    new purpose text
resTitle1 = "n/a"
jason = "PMMCU"
jemets = "GEMET - INSPIRE themes, version 1.0"
madate = "2021-11-15T00:00:00"
madate2 = "2010-12-08T00:00:00"
opendatanorme = "CC0, CC BY, CC BY-SA"
Pub = "publication"
Al = "GeoService"
reglement = "Selon reglèment"
commission = "Commission Regulation (EU) No 1089/2010 of 23 November 2010 implementing Directive 2007/2/EC of the European Parliament and of the Council as regards interoperability of spatial data sets and services"
conpass = "1"
domaine = "DQDomConsis"
balise = r'dqInfo/report'
att = "dimension"
valAtt = "horizontal"
type = "type"
newtype = "DQDomConsis"
balise2 = r'dqInfo/report/EvalMethTypeCd'
att2 = "value"
valAtt2 = "001"
balise3 = r'dqInfo/ScopeCD'
att3 = "value"
valAtt3 = "005"
########################################################################################

# fonction ppour mettre à jour des valeurs
def update_metadata(root):
    num_elements = 0
    # Recherche de la balise depuis root
    b = root.find(".//" + balise)
    if b is not None:
        # Affichage des attributs de la balise
        print ('Les attributs de la balise ' + balise + " sont : " + str(b.attrib))
        if b.get(att) is not None:
           # L'attribut recherché existe
           print ("L'attribut recherché existe (" + att + ")")
           print ("   Valeur actuelle : " + b.get(att))
           print ("   Nouvelle valeur : " + valAtt)
           b.set(att,valAtt)
           num_elements += 1
        if b.get(att) is None:
           # L'attribut recherché n'existe pas
           print ("L'attribut recherché n'existe pas (" + att + ")")
           print ("   Ajout de cet attribut avec la valeur : " + valAtt)
           b.set(att,valAtt)
           num_elements += 1
    else:
        print("La balise n'existe pas")





 ################################################################################
    return num_elements

    num_elements = 0
    # Recherche de la balise depuis root
    zeta = root.find(".//" + balise2)
    # balise de ressource quality report dimension
    if zeta is not None:
        # Affichage des attributs de la balise
        print ('Les attributs de la balise ' + balise2 + " sont : " + str(zeta.attrib))
        if zeta.get(att2) is not None:
            # L'attribut recherché existe
            print ("L'attribut recherché existe (" + att2 + ")")
            print ("Valeur actuelle : " + zeta.get(att2))
            print ("Nouvelle valeur : " + valAtt2)
            zeta.set(att2, valAtt2)
            num_elements += 1
        if zeta.get(att2) is None:
            # L'attribut recherché n'existe pas
            print ("L'attribut recherché n'existe pas (" + att2 + ")")
            print ("Ajout de cet attribut avec la valeur : " + valAtt2)
            zeta.set(att2, valAtt2)
            num_elements += 1
    else:
        print("La balise n'existe pas")
    return num_elements


def update_metadata(root):
    # Recherche de la balise depuis root
    geta = root.find(".//" + balise3)
    # balise de ressource quality report dimension
    if geta is not None:
        # Affichage des attributs de la balise
        print ('Les attributs de la balise ' + balise3 + " sont : " + str(zeta.attrib))
        if geta.get(att3) is not None:
            # L'attribut recherché existe
            print ("L'attribut recherché existe (" + att3 + ")")
            print ("Valeur actuelle : " + zeta.get(att3))
            print ("Nouvelle valeur : " + valAtt3)
            geta.set(att3, valAtt3)
            num_elements += 1
        if geta.get(att3) is None:
            # L'attribut recherché n'existe pas
            print ("L'attribut recherché n'existe pas (" + att3 + ")")
            print ("Ajout de cet attribut avec la valeur : " + valAtt3)
            geta.set(att3, valAtt3)
            num_elements += 1
    else:
        print("La balise n'existe pas")
    return num_elements





#######################################################################################

# function to update purpose and credits in metadata
def update_metadata(root):
    num_elements = 0
    for child in root:
        print(child.tag, child.attrib)
        # modify purpose element's text
        # there is only supposed to be one purpose element in metadata
        # replace purpose element text if element exists
        # if element doesn't exist, do nothing
    purposeEls = root.findall(".//formatVer")
    for element in purposeEls:
        if element.text is not None:
            element.text = resTitle1
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls1 = root.findall(".//idCredit")
    for element in purposeEls1:
        if element.text is not None:
            element.text = jason
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls2 = root.findall(".//useLimit")
    for element in purposeEls2:
        if element.text is not None:
            element.text = opendatanorme
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls2 = root.findall(".//identCode")
    for element in purposeEls2:
        if element.text is not None:
            element.text = Pub
            num_elements += 1

    # modify purpose element's text
    # there is only supposed to be one purpose element in metadata
    # replace purpose element text if element exists
    # if element doesn't exist, do nothing
    purposeEls2 = root.findall(".//formatName")
    for element in purposeEls2:
        if element.text is not None:
            element.text = Al
            num_elements += 1

        # add credits element to dataIdInfo parent, if the parent exists
        # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
        # ISO allows many idCredit elements, and many are supported in ArcGIS
        # append a new idCredit element with appropriate text, existing elements remain
    dataIdInfoEls = root.findall("./dataIdInfo")
    for element in dataIdInfoEls:
        if element:
            newCreditEl = ET.SubElement(element, "themeKeys")
            newCreditEl1 = ET.SubElement(newCreditEl, "thesaName")
            newCreditEl2 = ET.SubElement(newCreditEl1, "resTitle")
            newCreditEl2.text = jemets
            num_elements += 1

    # add credits element to dataIdInfo parent, if the parent exists
    # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
    # ISO allows many idCredit elements, and many are supported in ArcGIS
    # append a new idCredit element with appropriate text, existing elements remain
    dataIdInfoEls = root.findall("./dataIdInfo")
    for element in dataIdInfoEls:
        if element.text is not None:
            newCreditEl = ET.SubElement(element, "themeKeys")
            newCreditEl1 = ET.SubElement(newCreditEl, "thesaName")
            newCreditEl2 = ET.SubElement(newCreditEl1, "date")
            newCreditEl3 = ET.SubElement(newCreditEl1, "pubDate")
            newCreditEl3.time = madate
            num_elements += 1
    ################################################################################################
    # modif champ quality

    # add credits element to dataIdInfo parent, if the parent exists
    # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
    # ISO allows many idCredit elements, and many are supported in ArcGIS
    # append a new idCredit element with appropriate text, existing elements remain
    dataIdInfoEls1 = root.findall("./dqInfo")
    # for element in dataIdInfoEls1:
    #    if element.text is not None:
    #       newCreditcom = ET.SubElement(element, "report")
    #        newCreditcom1 = ET.SubElement(newCreditcom, "measResult")
    #        newCreditcom2 = ET.SubElement(newCreditcom1, "ConResult")
    #        newCreditcom3 = ET.SubElement(newCreditcom2, "conSpec")
    #        newCreditcom4 = ET.SubElement(newCreditcom3, "resTitle")
    #        newCreditcom4.text = commission
    #        num_elements += 1


    # add credits element to dataIdInfo parent, if the parent exists
    # ISO allows many dataIdInfo groups; ArcGIS supports only one, so get the 1st
    # ISO allows many idCredit elements, and many are supported in ArcGIS
    # append a new idCredit element with appropriate text, existing elements remain
    for element in dataIdInfoEls1:
        if element:
            newCreditreg = ET.SubElement(element, "report")
            newCreditreg1 = ET.SubElement(newCreditreg, "measResult")
            newCreditreg2 = ET.SubElement(newCreditreg1, "ConResult")
            newCreditreg3 = ET.SubElement(newCreditreg2, "conSpec")
            newCreditreg4 = ET.SubElement(newCreditreg3, "resAltTitle")
            newCredit4 = ET.SubElement(newCreditreg3, "collTitle")
            newCreditEll4 = ET.SubElement(newCreditreg3, "date")
            newCreditEll5 = ET.SubElement(newCreditEll4, "pubDate")
            newCreditcom4 = ET.SubElement(newCreditreg3, "resTitle")
            newPass4 = ET.SubElement(newCreditreg2, "conPass")  # type: Element

            newCreditcom4.text = commission
            newCreditreg4.text = reglement
            newCredit4.text = reglement
            newCreditEll5.text = madate2
            newPass4.text = conpass
            newCreditreg.text = domaine

            num_elements += 1


    return num_elements


# get and save item metadata
for item in Source_Metadata:
    arcpy.AddMessage("Item: {0}".format(item))

    # get the item's metadata xml
    item_md = md.Metadata(item)
    metadata_xml_string = item_md.xml

    # create an ElementTree object from the metadata XML string
    root = ET.fromstring(metadata_xml_string)

    # call the update_metadata function to modify the item's metadata
    changes = update_metadata(root)

    if changes > 0:
        # get modified XML
        updated_xml_string = ET.tostring(root, encoding="utf-8")

        # import result back into metadata
        arcpy.AddMessage("Saving updated metadata with the item...")
        item_md.xml = updated_xml_string
        item_md.save()
    else:
        arcpy.AddMessage("No changes to save")

arcpy.AddMessage('Finished updating metadata for all source metadataA items')

 

but that don't change my under-tag do you know what it's donc't work please?

 

0 Kudos
DanPatterson
MVP Esteemed Contributor

I don't see how line 11 fixed the problem, you need to throw some print or AddMessage statements in and we need to see what the output is as you progress through the script


... sort of retired...
0 Kudos
danielROUFFART1
Emerging Contributor

just when i put all of the text in the same line.

so for the rest arcgisPro say :

Heure de début : vendredi 31 décembre 2021 14:17:54
valeur modifiee pour balise 1 et 2
Item: Y:\SIG-GEOSERVICES\3_OPENDATA_SIG\METADONNEES\Developpement\Metadonnees_SDE\Test_Esri.gdb\agri_MdGrosAcces
Saving updated metadata with the item...
Finished updating metadata for all source metadataA items
réussie à vendredi 31 décembre 2021 14:17:54 (temps écoulé : 0,81 secondes)

 

so for the script he do every change but in the reality the scritp don't change the valor when it is in a tag

<

 

d<qInfo xmlns=""><dqScope><scpLvl><ScopeCd value="005"/></scpLvl></dqScope><dataLineage><statement>A remplir</statement></dataLineage><report xmlns="" type="DQNonQuanAttAcc" dimension="horizontal">

 

 

 

 

0 Kudos