0

I am facing with another problem.

I have kind of XML file with example code:

<case classname="perf" name="device">
    <Type>GET</Type>
    <Name>xxx</Name>
    <Request>Something</Request>
</case>

<case2 name="device_n>
    <Type>GET</Type>
    <Name>yyy</Name>
    <Request>Something</Request>
</case2>

<case...n>
...
</case...n>

How can I replace xxx to be named 'device' and yyy in case2 to be device_n?

I think something like that could be OK, but don't know how to write it:

with open('some_xml.xml') as parsed:
    if line in parsed.readlines.startswith("name="):
        line.replace('', "name=... #what's now?

This should be somekind of iterator because I have a lot of cases.

2
  • 1
    In case 3 the replacement of yyy is device_n or device_3? Commented Aug 6, 2020 at 15:56
  • 2
    did you tried your code ? It makes no sense. readlines is a function which neads (). readlines() gives list and list doesn't have startswith(). String has function startswith() but name= is not at the beginning of the line so checking startswith("name=") makes no sense. Other problem is that xxx is in diffferent line then "name=" so you can't use replace in the same line. Commented Aug 6, 2020 at 17:10

2 Answers 2

2

There may be a more clever way to do this with regex, but basic string searching seems to work:

import io

data = '''
<case classname="perf" name="device">
    <Type>GET</Type>
    <Name>xxx</Name>
    <Request>Something</Request>
</case>

<case2 name="device_n">
    <Type>GET</Type>
    <Name>yyy</Name>
    <Request>Something</Request>
</case2>'''

strOut="" # new string
f = io.StringIO(data)  # load string data as file text
for rowx in f:  # each line in data
    row = rowx.rstrip()  # remove newline
    if ' name="' in row: # <case name=...>
        nm = row[row.index(' name="')+7:len(row)-2] # get name
    if "<Name>" in row and nm:  # <Name>....
        idx = row.index("<Name>") + 6
        strOut += row[:idx] + nm + "</Name>\n"  # set name field here
        nm = ""  # in case bad block, don't copy wrong name
    else:
        strOut += row + "\n"  # copy line to new string

print(strOut)

Output

<case classname="perf" name="device">
    <Type>GET</Type>
    <Name>device</Name>
    <Request>Something</Request>
</case>

<case2 name="device_n">
    <Type>GET</Type>
    <Name>device_n</Name>
    <Request>Something</Request>
</case2>
Sign up to request clarification or add additional context in comments.

4 Comments

And the last question, how to make your script to change (according to my first post) from name="device" to name='xxx' vice versa?
I updated the answer, see the comment set name field here
Yep, thanks, but when I change the </Name>\n to ' name="' it still doesn't work.
</Name>\n is the end tag. Don't change that. If you want a different name, change the nm variable: strOut += row[:idx] + "MyNewName" + "</Name>\n"
0

A different approach (using xml parsing)

import xml.etree.ElementTree as ET

to_replace = {".//case/Name":'device',".//case2/Name":'device_n'}
xml = '''<r>
<case classname="perf" name="device">
    <Type>GET</Type>
    <Name>xxx</Name>
    <Request>Something</Request>
</case>

<case2 name="device_n">
    <Type>GET</Type>
    <Name>yyy</Name>
    <Request>Something</Request>

 </case2>
  </r>'''
root = ET.fromstring(xml)
for x_path,new_val in to_replace.items():
  ele = root.find(x_path)
  ele.text = new_val
ET.dump(root)

output

<r>
<case classname="perf" name="device">
    <Type>GET</Type>
    <Name>device</Name>
    <Request>Something</Request>
</case>

<case2 name="device_n">
    <Type>GET</Type>
    <Name>device_n</Name>
    <Request>Something</Request>

 </case2>
  </r>

Comments

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.