-2

I have an xml file as follows:

 <sample>
  <attributes> xyz
  </attributes>
  </sample>

I want to add to the starting of xml:

 <!DOCTYPE sample SYSTEM "location/sample.dtd">

I have to use python 2.5 only. So, can anybody please suggest how can i have this. I want final xml file to be:

 <sample>
  <!DOCTYPE sample SYSTEM "location/sample.dtd">
  <attributes> xyz
  </attributes>
  </sample>
Learner
  • 453
  • 13
  • 29
  • would it be ok if you rewrote the whole file, or do you need to insert after ? – WildCard May 24 '16 at 12:35
  • @WildCard i am ok with both, you may suggest any one of these – Learner May 24 '16 at 12:40
  • is system a variable? – WildCard May 24 '16 at 12:42
  • @WildCard SYSTEM is the keyword it simply specifies that it is a private dtd. For more details go to http://xmlwriter.net/xml_guide/doctype_declaration.shtml – Learner May 24 '16 at 12:49
  • 2
    What did you try out yourself? At what point of [7.2. Reading and Writing Files](https://docs.python.org/2.6/tutorial/inputoutput.html#reading-and-writing-files) do you get lost? Also – minor – why do you want to create badly formed XML? – Jongware May 24 '16 at 12:55
  • @WildCard approach is the best solution. – Mauro Baraldi May 24 '16 at 12:59
  • 2
    @Learner according to your link "*The document type declaration must be placed between the XML declaration and the first element (root element) in the document*". Which means, your placement is invalid. – gre_gor May 24 '16 at 13:40

2 Answers2

0

As a generalization of previous answer:

fp = open(xml_filepath, 'r')
content = fp.readlines()
fp.close()

final_content = content[:1]
final_content.append('<!DOCTYPE sample SYSTEM "location/sample.dtd">')
final_content.extend(content[1:])

fp = open(xml_filepath, 'w')
fp.writelines(final_content)
fp.close()
Schmouk
  • 327
  • 2
  • 6
  • And if you want to insert content in any other line than the second one, let say in (n+1)-th position: content = content[:n].append('...').extend(content[n:]) – Schmouk May 24 '16 at 13:05
  • i did as you told but getting error as 'str' object has no attribute 'append' – Learner May 24 '16 at 16:29
  • ok. My mistake is a typo. The solution should read: content = content[:1].append('...').extend(content[1:]), just as in previous comment, replacing 'n' with '1'. content[0] is really a string, while content[:1] is a list containing only the first item of the former list. – Schmouk May 24 '16 at 21:07
  • after correcting typo saying AttributeError: 'NoneType' object has no attribute 'extend'. :/ – Learner May 25 '16 at 04:56
  • Well, Learner, you're right. This is due to the nature of append() and extend() which modify lists in place and do not return a reference to their new content. I have just discovered this right now... So, things have to be done with a couple of instructions: final_content = content[:1]; final_content.append(' – Schmouk May 25 '16 at 07:47
  • The upper code has now been added to the answer. – Schmouk May 25 '16 at 13:15
-1

the following code will write and or overwrite file.xml in the current directory of your python script.. if you would like to write file.xml to a certain directory let me know.

from __future__ import with_statement



with open('file.xml', 'w') as file:
    file.write(r'''
<sample>
<!DOCTYPE sample SYSTEM "location/sample.dtd">
<attributes> xyz
</attributes>
</sample>''')
WildCard
  • 527
  • 3
  • 8
  • actually the solution you provide is ok if xml file is small but the actual xml is pretty huge and adding dtd info like that is not that clean way. So, is there any clean way where i do not need to provide complete xml and juzt tell the line no. of where to add dtd. – Learner May 24 '16 at 13:00
  • ok, I can work with that. I don't know much about the file you are writing, how many times does occur in the file? – WildCard May 24 '16 at 13:05
  • I am pretty sure he wants to insert the doctype into an arbitrary XML file. Writing a fixed XML is quite useless. – gre_gor May 24 '16 at 13:47