问题
There is a jsx file with contents
<import name="abcd" color="green" age="25" />
<View color={dsdssd}>
<IBG
color={[color.imagecolor, color.image125]}
imageStyle={[styles.imageStyle, styles.image125]}
source={{ uri: contents.aimeecard }} >
<View color={styles.titleContainer}>
<Text color={[{green: 45}, styles.mainTileText]}</Text>
<View color={[abcde.text]} />
</View>
</View>
I need to fetch the details of first line using python script: Expected output name="abcd" color="green" age="25"
Also the path of jsx file is passed through list ex: [abcd/file1.jsx , dcef/file2.jsx]
Python code tried for fetching jsx file through the list
for file in jsx_path:
data = md.parse("file")
print( file.firstChild.tagName )
Values are not fetched and getting error.
Can anyone help me in resolving this?
回答1:
Assuming jsx_path
is the list containing all the paths to the jsx files, you can iterate over each and use a context manager to avoid closing explicitly the files like so:
data = ""
for file in jsx_path:
with open(file) as f:
data += f.readline()[8:-4] + "\n"
print(data) # name="abcd" color="green" age="25"
Following your comment, if you want to output it as a dict, you can tweak the previous code:
import re
data = []
for file in jsx_path:
with open(file) as f:
data.append(re.split('\W+|=', f.readline()[8:-4]))
data_dict = []
for d in data:
data_dict.append({key:value for (key, value) in zip(d[::2], d[1::2])})
print(data_dict) # {'name': 'abcd', 'color': 'green', 'age': '25'}
Note that this is a hack. I only read the JSX file sequentially because your use case is simple enough to do so. You can also use a dedicated parser by extending the stlib class HTMLParser
:
from html.parser import HTMLParser
class JSXImportParser(HTMLParser):
def handle_starttag(self, tag, attrs):
if tag == "import":
self._import_attrs = {key:value for (key, value) in attrs}
@property
def import_attrs(self):
return self._import_attrs
parser = JSXImportParser()
data = []
for file in jsx_path:
with open(file) as f:
parser.feed(f.read())
data.append(parser.import_attrs)
print(data) # [{'name': 'abcd', 'color': 'green', 'age': '25'}]
Note that this only extracts the details of the last import tag in each file, you can alter this behavior by tweaking the _import_attrs
class attribute.
Edit: Following your additional comment about the requirement to use an XML parser library, the same thing can be achieved using ElementTree
by sampling the file to extract only what's interesting for you (the import tag):
import xml.etree.ElementTree as ET
data = []
for file in jsx_path:
with open(file) as f:
import_statement = ET.XML(f.readline())
data.append(import_statement.attrib)
print(data) # [{'name': 'abcd', 'color': 'green', 'age': '25'}]
Of course this only works if the import statement is on the first line, if it's not the case, you'll have to locate it first before calling ET.XML
.
来源:https://stackoverflow.com/questions/64249299/parse-a-jsx-file-to-extract-the-attributes-of-the-import-statement