首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python解析xml中节点前的注释

使用Python解析xml中节点前的注释
EN

Stack Overflow用户
提问于 2019-01-17 05:07:50
回答 1查看 41关注 0票数 0

下面是我从中解析数据的xml节点示例的格式:

代码语言:javascript
复制
<!-- /StationName/BACnetTemp/MNB_1_HX/HiPressureAlarm -->
<node name="HiPressureAlarm" class="tridium.control.BinaryInputNode" module="coreRuntime" release="2.301.535.v1">
  <properties>
    <position><x>576</x><y>866</y></position>
    <timeDelay>
      <duration>60</duration>
    </timeDelay>
    <eventEnable>
      <toOffnormal>true</toOffnormal>
      <toFault>false</toFault>
      <toNormal>true</toNormal>
    </eventEnable>
    <alarmText>MCD Basement Re-Heat High Pressure Alarm</alarmText>
    <changeOfStateTime>2018-05-07T08:55:04.09-4</changeOfStateTime>
    <changeOfStateCount>848</changeOfStateCount>
    <elapsedActiveTime>
      <duration>126872</duration>
    </elapsedActiveTime>
    <activeInactiveText>
      <active>Alarm</active>
      <inactive>Normal</inactive>
    </activeInactiveText>
    <alarmValueEnabled>true</alarmValueEnabled>
  </properties>
</node>  <!-- HiPressureAlarm -->

开头的注释是我试图将一些数据导出到excel文件中的点的路径。除了能够将路径与从中提取数据的节点相关联之外,我已经完成了所有其他工作。

我可以使用以下代码将所有评论放在一个列表中:

代码语言:javascript
复制
comments=soup.findAll(text=lambda text:isinstance(text, Comment))

然后,我尝试执行以下操作来查找注释并将其与路径相关联:

代码语言:javascript
复制
for comment in comments:
                x='/'+nodeName
                if x in comment:
                    nodePath = comment

问题是有几个具有不同路径的同名节点,所以它为每个节点提供了相同的路径。因此,我在for循环之后添加了以下代码:

代码语言:javascript
复制
if nodePath in comments:
                comments.remove(nodePath)

这应该是可行的,但是下一个问题是xml中有几个相同注释的实例,并且顺序与查找节点及其数据的顺序不匹配,因此路径与正确的节点不匹配。

有没有办法找到节点,然后将它前面的注释赋给一个变量,然后解析到excel中?

下面是我解析数据的完整代码:

代码语言:javascript
复制
def alarms(self,soup):
        alarms=soup.find_all('toOffnormal')
        comments=soup.findAll(text=lambda text:isinstance(text, Comment))
        nodeStartList=[]
        for alarm in alarms:
            nodeStart=alarm.parent.parent.parent
            nodeStartList.append(nodeStart)
        dataList=[]
        for item in nodeStartList:
            nodeName=item['name']
            for comment in comments:
                x='/'+nodeName
                if x in comment:
                    nodePath = comment
            if nodePath in comments:
                comments.remove(nodePath)
            if item.find('timeDelay')!= None:
                timeDelay=item.find('timeDelay').get_text("|", strip=True)
            else:
                timeDelay='0'

            if item.find('eventEnable')!=None:
                toOffnormal=item.find('toOffnormal').get_text("| ", strip=True)
                toFault=item.find('toFault').get_text("| ", strip=True)
                toNormal=item.find('toNormal').get_text("| ", strip=True)
            else:
                toOffnormal='false'
                toFault='false'
                toNormal='false'

            alarmText=item.find('alarmText').get_text("| ", strip=True)


            if item.find('highLimit')!= None:
                highLimit=item.find('highLimit').get_text("| ", strip=True)
            else:
                highLimit='N/A'

            if item.find('lowLimit')!= None:
                lowLimit=item.find('lowLimit').get_text("| ", strip=True)
            else:
                lowLimit='N/A'

            if item.find('deadband'):
                deadband=item.find('deadband').get_text("| ", strip=True)
            else:
                deadband='N/A'

            if item.find('lowLimitEnabled'):
                lowLimitEnabled=item.find('lowLimitEnabled').get_text("| ", strip=True)
            else:
                lowLimitEnabled='false'

            if item.find('highLimitEnabled'):
                highLimitEnabled=item.find('highLimitEnabled').get_text("| ", strip=True)
            else:
                highLimitEnabled='false'

            itemList=[nodeName,nodePath,timeDelay,toOffnormal,toFault,toNormal,alarmText,highLimit,lowLimit,deadband,lowLimitEnabled,highLimitEnabled]
            dataList.append(itemList)

        self.df=pandas.DataFrame(dataList)
        self.df.columns=['pointName','pointPath','timeDelay','toOffnormal','toFault','toNormal','alarmText','highLimit','lowLimit','deadband','lowLimitEnabled','highLimitEnabled']
        return self.df
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-19 04:31:30

我可以通过在第10行之后插入nodePath=item.previous_element.previous_element来实现我的目标。我的结果如下:

代码语言:javascript
复制
def alarms(self,soup):
        alarms=soup.find_all('toOffnormal')
        #comments=soup.findAll(text=lambda text:isinstance(text, Comment))
        nodeStartList=[]
        for alarm in alarms:
            nodeStart=alarm.parent.parent.parent
            nodeStartList.append(nodeStart)
        dataList=[]
        for item in nodeStartList:
            nodeName=item['name']
            nodePath=item.previous_element.previous_element
            #for comment in comments:
                #x='/'+nodeName
                #if x in comment:
                    #nodePath = comment
            #if nodePath in comments:
                #comments.remove(nodePath)
            if item.find('timeDelay')!= None:
                timeDelay=item.find('timeDelay').get_text("|", strip=True)
            else:
                timeDelay='0'

            if item.find('eventEnable')!=None:
                toOffnormal=item.find('toOffnormal').get_text("| ", strip=True)
                toFault=item.find('toFault').get_text("| ", strip=True)
                toNormal=item.find('toNormal').get_text("| ", strip=True)
            else:
                toOffnormal='false'
                toFault='false'
                toNormal='false'

            alarmText=item.find('alarmText').get_text("| ", strip=True)


            if item.find('highLimit')!= None:
                highLimit=item.find('highLimit').get_text("| ", strip=True)
            else:
                highLimit='N/A'

            if item.find('lowLimit')!= None:
                lowLimit=item.find('lowLimit').get_text("| ", strip=True)
            else:
                lowLimit='N/A'

            if item.find('deadband'):
                deadband=item.find('deadband').get_text("| ", strip=True)
            else:
                deadband='N/A'

            if item.find('lowLimitEnabled'):
                lowLimitEnabled=item.find('lowLimitEnabled').get_text("| ", strip=True)
            else:
                lowLimitEnabled='false'

            if item.find('highLimitEnabled'):
                highLimitEnabled=item.find('highLimitEnabled').get_text("| ", strip=True)
            else:
                highLimitEnabled='false'

            itemList=[nodeName,nodePath,timeDelay,toOffnormal,toFault,toNormal,alarmText,highLimit,lowLimit,deadband,lowLimitEnabled,highLimitEnabled]
            dataList.append(itemList)

        self.df=pandas.DataFrame(dataList)
        self.df.columns=['pointName','pointPath','timeDelay','toOffnormal','toFault','toNormal','alarmText','highLimit','lowLimit','deadband','lowLimitEnabled','highLimitEnabled']
        return self.df
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54225396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档