python - 使用 lxml 解析 xml 文件

标签 python xml lxml

我正在尝试通过查找每个 Watts 标签并更改其中的文本来编辑 xml 文件。到目前为止,我已经设法更改了所有标签,但没有具体更改 Watts 标签。

我的解析器是:

from lxml import etree
tree = etree.parse("cycling.xml")
root = tree.getroot()

for watt in root.iter():
    if watt.tag == "Watts":
        watt.text = "strong"

tree.write("output.xml")

这使我的 cycling.xml 文件保持不变。 output.xml 中的一个片段(它也是 cycling.xml 文件,因为它没有改变)是:

<TrainingCenterDatabase xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
  <Activities>
    <Activity Sport="Biking">
      <Id>2018-05-06T20:49:56Z</Id>
      <Lap StartTime="2018-05-06T20:49:56Z">
        <TotalTimeSeconds>2495.363</TotalTimeSeconds>
        <DistanceMeters>15345</DistanceMeters>
        <MaximumSpeed>18.4</MaximumSpeed>
        <Calories>0</Calories>
        <Intensity>Active</Intensity>
        <TriggerMethod>Manual</TriggerMethod>
        <Track>
          <Trackpoint>
            <Time>2018-05-06T20:49:56Z</Time>
            <Position>
              <LatitudeDegrees>49.319297</LatitudeDegrees>
              <LongitudeDegrees>-123.024128</LongitudeDegrees>
            </Position>
            <HeartRateBpm>
              <Value>99</Value>
            </HeartRateBpm>
            <Extensions>
              <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">
                <Watts>0</Watts>
                <Speed>2</Speed>
              </TPX>
            </Extensions>
          </Trackpoint>

如果我更改我的解析器以更改所有标签:

for watt in root.iter():
    if watt.tag != "Watts":
        watt.text = "strong"

然后我的 output.xml 文件变成:

<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">strong<Activities>strong<Activity Sport="Biking">strong<Id>strong</Id>
      <Lap StartTime="2018-05-06T20:49:56Z">strong<TotalTimeSeconds>strong</TotalTimeSeconds>
        <DistanceMeters>strong</DistanceMeters>
        <MaximumSpeed>strong</MaximumSpeed>
        <Calories>strong</Calories>
        <Intensity>strong</Intensity>
        <TriggerMethod>strong</TriggerMethod>
        <Track>strong<Trackpoint>strong<Time>strong</Time>
            <Position>strong<LatitudeDegrees>strong</LatitudeDegrees>
              <LongitudeDegrees>strong</LongitudeDegrees>
            </Position>
            <HeartRateBpm>strong<Value>strong</Value>
            </HeartRateBpm>
            <Extensions>strong<TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">strong<Watts>strong</Watts>
                <Speed>strong</Speed>
              </TPX>
            </Extensions>
          </Trackpoint>
          <Trackpoint>strong<Time>strong</Time>
            <Position>strong<LatitudeDegrees>strong</LatitudeDegrees>
              <LongitudeDegrees>strong</LongitudeDegrees>
            </Position>
            <AltitudeMeters>strong</AltitudeMeters>
            <HeartRateBpm>strong<Value>strong</Value>
            </HeartRateBpm>
            <Extensions>strong<TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2">strong<Watts>strong</Watts>
                <Speed>strong</Speed>
              </TPX>
            </Extensions>
          </Trackpoint>
  1. 如何才能只更改 Watts 标签?
  2. 我不明白 root = tree.getroot() 的作用。我只是想我会同时问这个问题,尽管我不确定它对我的特定问题是否重要。

最佳答案

您的文档定义了一个默认的 XML 命名空间。查看开始标记末尾的 xmlns= 属性:

<TrainingCenterDatabase
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">

这意味着您的文档中没有名为“Watts”的元素;您需要使用适当的命名空间来限定标签名称。如果您在我们的循环中打印出 watt.tag 的值,您将看到:

$ python filter.py 
{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}TrainingCenterDatabase
[...]
{http://www.garmin.com/xmlschemas/ActivityExtension/v2}Watts
{http://www.garmin.com/xmlschemas/ActivityExtension/v2}Speed

考虑到这一点,您可以修改您的过滤器,使其看起来像 这个:

from lxml import etree
tree = etree.parse("cycling.xml")
root = tree.getroot()

for watt in root.iter():
    if watt.tag == "{http://www.garmin.com/xmlschemas/ActivityExtension/v2}Watts":
        watt.text = "strong"

tree.write("output.xml")

您可以在 lxml documentation 中阅读更多关于命名空间处理的信息.

关于python - 使用 lxml 解析 xml 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50458900/

相关文章:

Python zipfile 从二进制文件中删除执行权限

python - pandas 应用一个新列

python - 使用 Sublime Text 3 设置 Python 3 构建系统

python - 使用 lxml lib 读取 xml 从 xmlns 标记中获取奇怪的字符串

Python lxml 更改标签层次结构?

python - 如何从 webapp2 中的 cookies/headers/session 中决定语言?

xml - rdf :resource, rdf:about 和 rdf:ID 的区别

java - 在 XML 文档中查找所有 namespace 声明 - xPath 1.0 与 xPath 2.0

c# - 从azure apim中的XML响应获取属性值

python - 如何使用 lxml 有效地解析这个包含嵌套元素的巨大 XML 文件?