如何将xml数据解析成不同的格式?

问题描述 投票:0回答:2

我有以下xml格式的数据。

 <UserStaging>
    <Staging>
      <Stage Type="Stage1" Start="0" />
      <Stage Type="Stage2" Start="50"/>
      <Stage Type="Stage3" Start="100" />
    </Staging>
 </UserStaging>

我必须以这种格式得到它:

<epoch><epoch_start>0</epoch_start<epoch_end>50</epoch_end><stage>NREM1</stage></epoch>   
<epoch><epoch_start>50</epoch_start<epoch_end>100</epoch_end<stage>NREM2</stage></epoch>
<epoch><epoch_start>100</epoch_start<epoch_end>9999</epoch_end<stage>NREM3</stage></epoch>

其中Stage1是NREM1,Stage2是NREM2,依此类推,项目的“epoch_end”是以下项目的“开始”。纪元时间是可变的。

我如何用例如python解析xml数据?有没有更好的方法,然后使用像minidump这样的工作来完成工作?适当的解析命令会是什么样的?谢谢你的回复。

python xml parsing xml-parsing
2个回答
0
投票

这种工作的常用工具是XSLT。在这种情况下,可以使用XSLT 1.0轻松完成作业,XSLT 1.0可供Python使用:

<xsl:stylesheet...

<xsl:template match="Stage">
  <epoch>
    <epoch_start>
      <xsl:value-of select="@Start"/>
    </epoch_start>
    <epoch_end>
      <xsl:variable name="next" select="following-sibling::*[1]"/>
      <xsl:choose>
         <xsl:when test="$next">
           <xsl:value-of select="$next/@Start"/>
         <xsl:when>
         <xsl:otherwise>9999</xsl:otherwise>
      </xsl:choose>
    </epoch_end>
    <stage>NREM<xsl:number/></stage>
  </epoch>
</xsl:template>

</xsl:stylesheet>

0
投票

基于xml.etree.ElementTree的解决方案。可以在没有用于调试的dicts的中间列表的情况下实现。

import xml.etree.ElementTree as ET

data = '''<UserStaging>
    <Staging>
      <Stage Type="Stage1" Start="0" />
      <Stage Type="Stage2" Start="50"/>
      <Stage Type="Stage3" Start="100" />
    </Staging>
 </UserStaging>'''

tree = ET.fromstring(data)
new_data = []
start = 0
for idx, stage in enumerate(tree.iter('Stage')):
    new_data.append({'start': stage.attrib['Start'],
                     'stage': 'NREM{}'.format(idx + 1)})
    if idx > 0:
        new_data[idx - 1]['end'] = stage.attrib['Start']

root = ET.Element("UserStaging")
for idx, entry in enumerate(new_data):
    epoch = ET.SubElement(root, "epoch")
    start = ET.SubElement(epoch, "epoch_start").text = entry['start']
    end = ET.SubElement(epoch, "epoch_end").text = entry['end'] if idx < len(new_data) - 1 else '9999'
    stage = ET.SubElement(epoch, "stage").text = entry['stage']

ET.dump(root)

输出:

<UserStaging>
   <epoch>
      <epoch_start>0</epoch_start>
      <epoch_end>50</epoch_end>
      <stage>NREM1</stage>
   </epoch>
   <epoch>
      <epoch_start>50</epoch_start>
      <epoch_end>100</epoch_end>
      <stage>NREM2</stage>
   </epoch>
   <epoch>
      <epoch_start>100</epoch_start>
      <epoch_end>9999</epoch_end>
      <stage>NREM3</stage>
   </epoch>
</UserStaging>
© www.soinside.com 2019 - 2024. All rights reserved.