3

I have an XML file (example below) - I am using Python 2.7

I want to change all occurences of stag to read prod. The word "stag" lies within a URL. I don't want to change the entire url just the occurence of the word stag - see example:

url=http://stag/comp/rest/services/editor/hyd/MapServer

want to change to:

url=http://prod/comp/rest/services/editor/hyd/MapServer

<Map FullExtent="-136163.9492,444360.64787994,-525467.175315,43020.05517682" InitialExtent="-32989.136772,6307.55418809,-4753.07696,5137.2783653">
<LayerList>
  <Items>
    <Item ID="17" />
    <Item ID="20" IsExpanded="true" Name="Reference Data" Visible="true">
      <Items>
        <Item ID="30" />
        <Item ID="34" VisibleInLayerList="false" />
        <Item ID="22" VisibleInLayerList="false" />
        <Item ID="41" VisibleInLayerList="false" />
        <Item ID="16" />
        <Item ID="37" />
        <Item ID="24" />
        <Item ID="39" />
        <Item ID="32" />
        <Item ID="28" />
        <Item ID="26" />
      </Items>
    </Item>
    <Item ID="19" IsExpanded="true" Name="Basemaps" Visible="true">
      <Items>
        <Item ID="12" />
        <Item ID="11" />
      </Items>
    </Item>
  </Items>
</LayerList>
<MapServices>
  <MapService ConnectionString="url=http://stag/comp/rest/services/editor/hyd/MapServer" DefaultAllowSymbolization="true" DisplayName="hydrants" Function="Operational" ID="17" ImageFormat="Png32" ImpersonateWithActor="false" IncludeCopyright="false" IncludeInLayerList="true" InstantSearch="false" InstantSearchAttachments="false" IsExpanded="true" MaximumScale="500" MinimumScale="7500" Opacity="1" OverrideTemporalSettings="false" PasswordEncrypted="false" ProviderInvariantName="Geocortex.Gis.Services.ArcGisServer.Rest" SearchNonTextFields="true" SupportedImageHeight="0" SupportedImageWidth="0" UseHttpAuthentication="false" Visible="true">
    <CachedServiceData />
    <Layers>
      <Layer AllowSymbolization="true" CanCopyFeature="true" DisplayName="Hydrants" FeatureDescription="&lt;div&gt;&lt;span style=&quot;font-family: Arial, Verdana; font-size: 13.3333px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Hydrant ID: &lt;/span&gt;&lt;/span&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;{FIRE_HYDRANT_ID}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;span style=&quot;font-size: 13.3333px; font-family: Arial, Verdana;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;span style=&quot;font-size: 13.3333px; font-family: Arial, Verdana;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Work Order Number&lt;/span&gt;: {WORK_ORDER_NUM}&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;span style=&quot;font-size: 13.3333px; font-family: Arial, Verdana;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Make&lt;/span&gt;: {MAKE}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Elevation&lt;/span&gt;: {ELEVATION}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Hydrant Number&lt;/span&gt;: {HYDRANT_NUM}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Hydrant Size&lt;/span&gt;: {HYDRANT_SIZE}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;br/&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Verdana; font-size: 10pt; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;font face=&quot;Arial, Verdana&quot;&gt;&lt;span style=&quot;font-size: 13.3333px;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Install Year&lt;/span&gt;: {INSTALL_YEAR}&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;" FeatureLabel="&lt;b&gt;Fire Hydrant&lt;/b&gt;" Identifiable="true" IncludeInLayerList="true" IncludeInLegend="true" IsCatalogLayer="false" IsExpanded="true" LayerListID="30" Name="SJPWPUB.FIRE_HYDRANT" NativeID="0" Queryable="true" Searchable="true" ShowFeatureHyperlinks="ShowAll" ShowLabels="true" ShowMapTips="true" Snappable="true" SnappingEnabled="false" UnconfiguredFieldsCanSymbolizeClassBreaks="false" UnconfiguredFieldsCanSymbolizeUniqueValue="false" UnconfiguredFieldsSearchable="false" UnconfiguredFieldsVisible="false" UnconfiguredRelationshipsVisible="true" Visible="true">
        <Fields>
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="5" DisplayName="Hydrant Number" FocusField="false" Name="HYDRANT_NUM" Searchable="true" Visible="true" />
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="2" DisplayName="Work Order Number" FocusField="false" Name="WORK_ORDER_NUM" Searchable="false" Visible="true" />
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="3" DisplayName="Make" FocusField="false" Name="MAKE" Searchable="false" Visible="true" />
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="6" DisplayName="Hydrant Size" FocusField="false" Name="HYDRANT_SIZE" Searchable="false" Visible="true" />
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="7" DisplayName="Install Year" FocusField="false" Name="INSTALL_YEAR" Searchable="false" Visible="true" />
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="4" DisplayName="Elevation" FocusField="false" Name="ELEVATION" Searchable="false" Visible="true" />
          <Field CanSymbolizeClassBreaks="false" CanSymbolizeUniqueValue="false" DisplayIndex="1" DisplayName="Fire Hydrant ID" FocusField="false" Name="OBJECTID" Searchable="false" Visible="true" />
        </Fields>
      </Layer>
    </Layers>
  </MapService>
</Map>

I've tried a couple different methods but none seem to work. Here's my latest attempt:

Prod_xml = r"C:/Users/ba/Documents/temp/Prod/Projects/Site.xml"

import lxml.etree as ET

with open(Prod_xml, 'rb+') as f:
    tree = ET.parse(f)
    root = tree.getroot()
    for elem in root.getiterator():
       if elem.text:
          elem.text.replace('stag', 'prod')
       if elem.tail:
          elem.tail.replace('stag', 'prod')

f.seek(0)
f.write(ET.tostring(tree, encoding='UTF-8', xml_declaration=True))
f.truncate()

This does not work. I am getting no error but the xml file is unchanged.

Any ideas on how to do this?

UPDATE

I'd like to use ElementTree option but I am getting the following error when I use the xml.etree.ElementTree script (It also removes the data within my xml file altogether):

Traceback (most recent call last):
  File "F:/Applications/Geocortex/MovingGeocortexFiles.py", line 56, in <module>
    ET.dump(f)
  File "C:\Python27\ArcGIS10.3\lib\xml\etree\ElementTree.py", line 1164, in dump
    elem.write(sys.stdout)
  File "C:\Python27\ArcGIS10.3\lib\xml\etree\ElementTree.py", line 817, in write
    self._root, encoding, default_namespace
  File "C:\Python27\ArcGIS10.3\lib\xml\etree\ElementTree.py", line 876, in _namespaces
    iterate = elem.getiterator # cET compatibility
AttributeError: 'file' object has no attribute 'getiterator'

1 Answer 1

5

I know this might be oversimplifying the problem, but wouldn't it be easier to just:

with open(filepath, 'r') as f:
    res = f.read().replace('http://stag', 'http://prod')

with open(filepath,'w') as f:
    f.write(res)

If you insist on parsing it as XML, you can do the following:

import xml.etree.ElementTree as ET

with open(filepath, 'r') as f:
    tree = ET.parse(f)

for n in tree.findall(".//"):
    for a in n.attrib:
        n.attrib[a] = n.attrib[a].replace("stag", "prod")

with open(filepath, 'w') as f:
    tree.write(f)
Sign up to request clarification or add additional context in comments.

5 Comments

This worked perfectly! I swear I tried this initially and was overthinking the problem since xml can be a bit complicated.
While this may work for this particular situation, do not treat XML like a text file. Parse and update node/attrib values with DOM handling. You can end breaking the well-formed tree and even attempt regex which is ill-advised for X/HTML documents.
I added an XML solution as well.
@LiranFunaro I'd like to use ElementTree option but I am getting an error when I use the xml.etree.ElementTree script (It also removes the data within my xml file altogether). See my update above
Sorry, my bad. I used dump wrong. Try my correction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.