首页 > 解决方案 > 解析 JSX 文件以提取 Import 语句的属性

问题描述

有一个包含内容的 jsx 文件

<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>

我需要使用 python 脚本获取第一行的详细信息: Expected output name="abcd" color="green" age="25"

jsx 文件的路径也通过列表 ex: [abcd/file1.jsx , dcef/file2.jsx]

Python 代码尝试通过列表获取 jsx 文件

for file in jsx_path:
   data = md.parse("file")
   print( file.firstChild.tagName )

未获取值并出现错误。

谁能帮我解决这个问题?

标签: pythonpython-3.xxmljsx

解决方案


假设jsx_path列表包含 jsx 文件的所有路径,您可以遍历每个路径并使用上下文管理器来避免显式关闭文件,如下所示:

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"

根据您的评论,如果您想将其作为字典输出,您可以调整前面的代码:

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'}

请注意,这是一个 hack。我只按顺序读取 JSX 文件,因为您的用例很简单。您还可以通过扩展 stlib 类来使用专用解析器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'}]

请注意,这仅提取每个文件中最后一个导入标记的详细信息,您可以通过调整_import_attrs类属性来更改此行为。

编辑:根据您对使用 XML 解析器库的要求的附加评论,可以ElementTree通过对文件进行采样以仅提取您感兴趣的内容(导入标记)来实现相同的目的:

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'}]

当然,这只有在 import 语句在第一行时才有效,如果不是这种情况,您必须在调用之前先找到它ET.XML


推荐阅读