'lxml.etree._Element' object has no attribute 'write' ??? (PYTHON) [duplicate] - python

This question already has answers here:
Write xml file using lxml library in Python
(5 answers)
Closed 9 years ago.
from lxml import etree
root = etree.Element('root1')
element = etree.SubElement(root, 'element1')
root.write( 'xmltree.xml' )
Error:
AttributeError: 'lxml.etree._Element' object has no attribute 'write'
how can I fix this?

Elements (like root) do not have a write method, but ElementTrees do:
from lxml import etree
root = etree.Element('root1')
element = etree.SubElement(root, 'element1')
tree = root.getroottree()
print(type(tree))
# <type 'lxml.etree._ElementTree'>
tree.write('xmltree.xml')
The documentation on tree.write is a little hard to find on the web. Here is the method's doc string:
In [7]: tree.write?
Type: builtin_function_or_method
Base Class: <type 'builtin_function_or_method'>
String Form: <built-in method write of lxml.etree._ElementTree object at 0x95c48cc>
Namespace: Interactive
Docstring:
write(self, file, encoding=None, method="xml",
pretty_print=False, xml_declaration=None, with_tail=True,
standalone=None, compression=0,
exclusive=False, with_comments=True)
Write the tree to a filename, file or file-like object.
Defaults to ASCII encoding and writing a declaration as needed.
The keyword argument 'method' selects the output method:
'xml', 'html', 'text' or 'c14n'. Default is 'xml'.
The ``exclusive`` and ``with_comments`` arguments are only
used with C14N output, where they request exclusive and
uncommented C14N serialisation respectively.
Passing a boolean value to the ``standalone`` option will
output an XML declaration with the corresponding
``standalone`` flag.
The ``compression`` option enables GZip compression level 1-9.

If you are wanting to save your new xml to a file then etree.tostring is the method to use.
E.g.
>>> from lxml import etree
>>> root = etree.Element('root1')
>>> element = etree.SubElement(root, 'element1')
>>> print etree.tostring(root,pretty_print=True) ## Print document
<root1>
<element1/>
</root1>
>>> with open('xmltree.xml','w') as f: ## Write document to file
... f.write(etree.tostring(root,pretty_print=True))
...
>>>

Related

StringIO() argument 1 must be string or buffer, not cStringIO.StringIO

I have a function that's reading a content object into a pandas dataframe.
import pandas as pd
from cStringIO import StringIO, InputType
def create_df(content):
assert content, "No content was provided, can't create dataframe"
if not isinstance(content, InputType):
content = StringIO(content)
content.seek(0)
return pd.read_csv(content)
However I keep getting the error TypeError: StringIO() argument 1 must be string or buffer, not cStringIO.StringIO
I checked the incoming type of the content prior to the StringIO() conversion inside the function and it's of type str. Without the conversion I get an error that the str object does not have a seek function. Any idea whats wrong here?
You only tested for InputType, which is a cStringIO.StringIO() instance that supports reading. You appear to have the other type, OutputType, the instance created for an instance that supports writing to:
>>> import cStringIO
>>> finput = cStringIO.StringIO('Hello world!') # the input type, it has data ready to read
>>> finput
<cStringIO.StringI object at 0x1034397a0>
>>> isinstance(finput, cStringIO.InputType)
True
>>> foutput = cStringIO.StringIO() # the output type, it is ready to receive data
>>> foutput
<cStringIO.StringO object at 0x102fb99d0>
>>> isinstance(foutput, cStringIO.OutputType)
True
You'd need to test for both types, just use a tuple of the two types as the second argument to isinstance():
from cStringIO import StringIO, InputType, OutputType
if not isinstance(content, (InputType, OutputType)):
content = StringIO(content)
or, and this is the better option, test for read and seek attributes, so you can also support regular files:
if not (hasattr(content, 'read') and hasattr(content, 'seek')):
# if not a file object, assume it is a string and wrap it in an in-memory file.
content = StringIO(content)
or you could just test for strings and [buffers](https://docs.python.org/2/library/functions.html#buffer(, since those are the only two types that StringIO() can support:
if isinstance(content, (str, buffer)):
# wrap strings into an in-memory file
content = StringIO(content)
This has the added bonus that any other file object in the Python library, including compressed files and tempfile.SpooledTemporaryFile() and io.BytesIO() will also be accepted and work.

Can't convert a string to JSON using python 3? [duplicate]

This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed 25 days ago.
In Python I'm getting an error:
Exception: (<type 'exceptions.AttributeError'>,
AttributeError("'str' object has no attribute 'read'",), <traceback object at 0x1543ab8>)
Given python code:
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.load(jsonStr)['data']['children']
What does this error mean and what did I do to cause it?
The problem is that for json.load you should pass a file like object with a read function defined. So either you use json.load(response) or json.loads(response.read()).
Ok, this is an old thread but.
I had a same issue, my problem was I used json.load instead of json.loads
This way, json has no problem with loading any kind of dictionary.
Official documentation
json.load - Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads - Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You need to open the file first. This doesn't work:
json_file = json.load('test.json')
But this works:
f = open('test.json')
json_file = json.load(f)
If you get a python error like this:
AttributeError: 'str' object has no attribute 'some_method'
You probably poisoned your object accidentally by overwriting your object with a string.
How to reproduce this error in python with a few lines of code:
#!/usr/bin/env python
import json
def foobar(json):
msg = json.loads(json)
foobar('{"batman": "yes"}')
Run it, which prints:
AttributeError: 'str' object has no attribute 'loads'
But change the name of the variablename, and it works fine:
#!/usr/bin/env python
import json
def foobar(jsonstring):
msg = json.loads(jsonstring)
foobar('{"batman": "yes"}')
This error is caused when you tried to run a method within a string. String has a few methods, but not the one you are invoking. So stop trying to invoke a method which String does not define and start looking for where you poisoned your object.
AttributeError("'str' object has no attribute 'read'",)
This means exactly what it says: something tried to find a .read attribute on the object that you gave it, and you gave it an object of type str (i.e., you gave it a string).
The error occurred here:
json.load(jsonStr)['data']['children']
Well, you aren't looking for read anywhere, so it must happen in the json.load function that you called (as indicated by the full traceback). That is because json.load is trying to .read the thing that you gave it, but you gave it jsonStr, which currently names a string (which you created by calling .read on the response).
Solution: don't call .read yourself; the function will do this, and is expecting you to give it the response directly so that it can do so.
You could also have figured this out by reading the built-in Python documentation for the function (try help(json.load), or for the entire module (try help(json)), or by checking the documentation for those functions on http://docs.python.org .
Instead of json.load() use json.loads() and it would work:
ex:
import json
from json import dumps
strinjJson = '{"event_type": "affected_element_added"}'
data = json.loads(strinjJson)
print(data)
So, don't use json.load(data.read()) use json.loads(data.read()):
def findMailOfDev(fileName):
file=open(fileName,'r')
data=file.read();
data=json.loads(data)
return data['mail']
use json.loads() function , put the s after that ... just a mistake btw i just realized after i searched error
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.loads(jsonStr)['data']['children']
try this
Open the file as a text file first
json_data = open("data.json", "r")
Now load it to dict
dict_data = json.load(json_data)
If you need to convert string to json. Then use loads() method instead of load(). load() function uses to load data from a file so used loads() to convert string to json object.
j_obj = json.loads('["label" : "data"]')

eyed3 file from bytes

Is it possible to modify the tags of a downloaded MP3, without writing it to the disk?
I am using
def downloadTrack(url)
track_data = requests.get(url)
audiofile = Mp3AudioInherited(track_data.content)
audiofile.initTag()
with the class Mp3AudioInherited inherited from core.AudioFile much like mp3.Mp3AudioFile. The only signficant difference:
class Mp3AudioInherited(core.AudioFile):
...
def _read(self):
with io.BytesIO(self.data) as file_obj:
self._tag = id3.Tag()
tag_found = self._tag.parse(file_obj, self._tag_version)
...
Unfortunately _tag.parse() throws a ValueError: Invalid type: <type '_io.BytesIO'>. Isn't BytesIO a file-like object?
Thanks and regards!
No, io.BytesIO objects are not file-like (i.e., they are not interchangeable with file objects) in Python 2. Try using StringIO.StringIO to get a memory-backed file-like object in Python 2.

Attribute error in python while parsing an XML

I am kinda new to Python. I am working on a project that parses an XML in Python and my Python code to do so is :
from xml.dom import minidom
from copy import copy
class Xmlparse:
def __init__(self, xmlfile):
self = minidom.parse(xmlfile)
def findadress(self):
itemlist =self.getElementsByTagName('addresses')
return itemlist[0].attributes['firstname'].value
if __name__ == '__main__':
with open("sample.xml") as f:
parse = Xmlparse(f)
print parse.findadress()
But when I run this code I get an output error:
AttributeError: Xmlparse instance has no attribute 'findadress'
And findadress function is spelled correctly in the main, but for some reason what so ever i am getting this error.
Any help is really appreciated.
And I also wanted to know, how can I validate the xml with an XSD schema in python?
"self = minidom.parse(xmlfile)" overwrites the Xmlparse object you just created. You want to assign the xml doc to a variable instead:
from xml.dom import minidom
from copy import copy
class Xmlparse:
def __init__(self, xmlfile):
self.doc = minidom.parse(xmlfile)
def findadress(self):
itemlist =self.doc.getElementsByTagName('addresses')
return itemlist[0].attributes['firstname'].value
the evil is in self = minidom.parse(xmlfile)

Adding a XML root attribute with hyphens in python XMLBuilder

I'm integrating with the google checkout api and all of their attributes include hyphens in their attribute values. So to create a request to charge an order I need to send an xml post that looks like:
<?xml version="1.0" encoding="UTF-8"?>
<charge-and-ship-order xmlns="http://checkout.google.com/schema/2" google-order-number="6014423719">
<amount currency="USD">335.55</amount>
</charge-and-ship-order>
I'm having trouble building that xml with the attribute "google-order-number". The following code works if I want to create an empty node:
>>> xml=XMLBuilder()
>>> xml << ('charge-and-ship-order, {'xmlns':'xxx','google-order-number':'3433'})
>>> str(xml)
>>> <charge-and-ship-order google-order-number="3433" xmlns="xxx" />
But If I try to child node for the amount using the documented way:
>>> xml=XMLBuilder()
>>> with xml('charge-and-ship-order', xmlns='xxx', google-order-number='3433'}):
>>> with xml('amount', currency="USD"):
>>> xml << '4.54'
I get an error saying:
SyntaxError: keyword can't be an expression
I've also tried:
>>> xml=XMLBuilder()
>>> with xml('charge-and-ship-order', {'xmlns':'xxx', 'google-order-number':'3433'}):
>>> with xml << 'test'
and I get a traceback in the XMLBuilder library saying
File "/xmlbuilder/xmlbuilder/__init__.py", line 102, in __call__
x(*dt,**mp)
File "/xmlbuilder/xmlbuilder/__init__.py", line 36, in __call__
text = "".join(dt)
TypeError: sequence item 0: expected string, dict found
Any Ideas how to use an attribute like that? I'm using the XMLBuilder library located at
http://pypi.python.org/pypi/xmlbuilder
You can pass the attributes in a dictionary like this:
function_call(**{'weird-named-key': 'value'})

Categories

Resources