Reputation: 385
I have an XML string output from a code. From the output I would like to join two lines that have a 'predicted_serotype'
string in them (this string is known as diff_string
):
<result type="MLST" value="96">
<result_data type="profile" value="43,47,49,49,41,15,3"/>
<result_data type="QC_minimum_consensus_depth" value="7"/>
<result_data type="QC_max_percentage_non_consensus_base" value="10.0"/>
<result_data type="QC_percentage_coverage" value="100"/>
<result_data type="QC_minimum_consensus_depth_for_all_loci" value="7,17,27,10,25,18,22" diff:update-attr="value:7,17,27,10,24,18,22"/>
<result_data type="QC_complete_pileup" value="TRUE"/>
<result_data type="QC_mean_consensus_depth" value="17.67"/>
<result_data type="QC_max_percentage_non_consensus_base_for_all_loci" value="10.0, 6.25, 3.45, 9.09, 5.88, 5.26, 5.41"/>
<result_data type="QC_mean_consensus_depth_for_all_loci" value="17.67, 32.49, 34.09, 23.44, 35.57, 29.02, 39.08" diff:update-attr="value:17.67, 32.49, 34.09, 23.44, 34.24, 29.02, 39.08"/>
<result_data type="QC_traffic_light" value="GREEN"/>
<result_data diff:insert="" type="predicted_serotype" diff:add-attr="type;value" value="('Schwarzengrund (Achtman)', 168), ('Schwarzengrund (PHE)', 83), ('Blockley (Achtman)', 1), ('Uppsala (Achtman)', 1), ('Oslo (Achtman)', 1), ('Schwarzengru (Achtman)', 1), ('Iv Rough:Z4,Z32:- (Achtman)', 1)"/>
<result_data type="predicted_serotype" value="('Schwarzengrund (PHE)', 13)" diff:delete=""/>
</result>
<gastro_prelim_st reason="not novel" success="false">
<type st="96"/>
</gastro_prelim_st>
I have written this code but it only adds a new line rather than joining the two lines:
diff_list = diff.split("\n")
for n,line in enumerate(diff_list):
if "predicted_serotype" in line:
diff_list[n] = "\n"+line.strip()
else:
diff_list[n]=line.rstrip()
print("\n".join(diff_list))
What I would like is an output like this:
<result type="MLST" value="96">
<result_data type="profile" value="43,47,49,49,41,15,3"/>
<result_data type="QC_minimum_consensus_depth" value="7"/>
<result_data type="QC_max_percentage_non_consensus_base" value="10.0"/>
<result_data type="QC_percentage_coverage" value="100"/>
<result_data type="QC_minimum_consensus_depth_for_all_loci" value="7,17,27,10,25,18,22" diff:update-attr="value:7,17,27,10,24,18,22"/>
<result_data type="QC_complete_pileup" value="TRUE"/>
<result_data type="QC_mean_consensus_depth" value="17.67"/>
<result_data type="QC_max_percentage_non_consensus_base_for_all_loci" value="10.0, 6.25, 3.45, 9.09, 5.88, 5.26, 5.41"/>
<result_data type="QC_mean_consensus_depth_for_all_loci" value="17.67, 32.49, 34.09, 23.44, 35.57, 29.02, 39.08" diff:update-attr="value:17.67, 32.49, 34.09, 23.44, 34.24, 29.02, 39.08"/>
<result_data type="QC_traffic_light" value="GREEN"/>
<result_data diff:insert="" type="predicted_serotype" diff:add-attr="type;value" value="('Schwarzengrund (Achtman)', 168), ('Schwarzengrund (PHE)', 83), ('Blockley (Achtman)', 1), ('Uppsala (Achtman)', 1), ('Oslo (Achtman)', 1), ('Schwarzengru (Achtman)', 1), ('Iv Rough:Z4,Z32:- (Achtman)', 1)"/><result_data type="predicted_serotype" value="('Schwarzengrund (PHE)', 13)" diff:delete=""/>
</result>
<gastro_prelim_st reason="not novel" success="false">
<type st="96"/>
</gastro_prelim_st>
Upvotes: 0
Views: 66
Reputation: 1054
That's the most efficient way I found to do it.
I tried to keep the code as explainable as I could.. you could shorten it if you'd like (;
goal_str = 'predicted_serotype'
lines = text.split('\n')
line_indexes = [lines.index(elem) for elem in lines if elem.find(goal_str) > -1]
desired_text = lines[line_indexes[0]] + ''.join([lines[index].strip() for index in line_indexes[1:]])
[lines.pop(index) for index in line_indexes[1:]]
lines[line_indexes[0]] = desired_text
fixed_text = '\n'.join(lines)
print(fixed_text)
Upvotes: 0
Reputation: 858
This should do the trick, we look for the first occurence of a line with predicted_serotype, and then if we meet another occurence, we remove it and add it to the first occurence.
diff_list = diff.split("\n")
first_serotype_line_nbr = 0
for n,line in enumerate(diff_list):
if "predicted_serotype" in line:
if first_serotype_line_nbr == 0:
first_serotype_line_nbr = n
else:
diff_list[first_serotype_line_nbr] += line.rstrip()
del(diff_list[n])
else:
diff_list[n]=line.rstrip()
print("\n".join(diff_list))
Upvotes: 1