使用REGEX检查带有脚本的XML节点

2024-03-29 12:30:35 发布

您现在位置:Python中文网/ 问答频道 /正文

这里有点问题,基本上我有一个网址,我使用了一个GET。 例如111.244.25.633/数据.XML(不用担心IP,它只是一个设备的组成部分)它返回一个XML文件。在

在数据.XML我们有一些节点和子节点。(就像一棵树) 例如,整个数据是这样封装的:(缩进意味着它是上面的子节点…等等)

 <Data>
   <DeviceData>
       <Info>
        <SerialNumber>154236</SerialNumber>
        <Ethernet>Y</Ethernet>
        <Wireless>N</Wireless>
        <Mac>00:25:F6:25:K9</Mac>
       </Info>
   </DeviceData>
 </Data>

基本上,我想使用正则表达式来检查子节点(就像我想确保序列号是一个6位数的数字,而不是其他的)

子节点总是被称为同一个东西(比如序列号、设备数据、数据……等等)

什么样的扩展/语言是最容易使用的?我知道基本的Python和BASH,我对C/C++很有了解……但是这对我来说更像是一个脚本任务。在

有什么想法吗?在

编辑:我忘了加上:我可能有更多或更少的XML标记(比如有些设备有更多的设置等等),所以我会在脚本中挑选特定的标记,而不是查看每一个标记……因为有些标记可能比其他标记多或少。在


Tags: 数据标记info脚本dataget节点mac
3条回答

如果您喜欢更具声明性的编写规则的方式(而不是python&lxml的过程化方法),也可以使用xslt2.0来实现这一点。在

比如:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

  <xsl:output method="text" />

  <xsl:template match="SerialNumber[matches( normalize-space(.), '^\d{6}$')]" >
    <xsl:value-of select="." /> Passes.
  </xsl:template>

  <xsl:template match="SerialNumber[not( matches( normalize-space(.), '^\d{6}$'))]" >
    <xsl:value-of select="." /> Fails.
  </xsl:template>

  <xsl:template match="text()">
    <!  override default template, output nothing  >
  </xsl:template>

</xsl:stylesheet>

将输出:

154236次传球。在

X154236失败。在

如果有很多规则需要检查,也许应该看看XML模式语言 比如Relax NG或{a2}。Schema是为比dtd更具表现力的XML文档编写语法的一种方法。使用模式语言编写声明性规则和,处理器编写XSLT代码,根据模式验证XML。在

请参阅此回复:Regular Expressions to parse template tags in XML

你的项目演示。。。在

from xml.etree import ElementTree
import re

def proper_SN(elem):
    if re.search('\d{6}', elem.text):
        return True
    return False

tree = ElementTree.parse('data.xml')
rows = tree.getiterator('SerialNumber')
for row in rows:
    print "SerialNumber: %s Passed = %s" % (row.text, proper_SN(row))

运行这个。。。在

^{pr2}$

编辑

我不确定XML会如何改变。。。假设您更改了DeviceData元素。。。在

 <Data>
   <DeviceData>
       <Info>
        <SerialNumber>154236</SerialNumber>
        <EngineVersion>12.0.4.13</EngineVersion>
        <MediaType>100BaseT</MediaType>
        <Ethernet>Y</Ethernet>
        <Wireless>N</Wireless>
        <Mac>00:25:F6:25:K9</Mac>
       </Info>
   </DeviceData>
 </Data>

使用简化的脚本。。。在

from xml.etree import ElementTree
import re

def proper_SN(elem):
    if re.search('\d{6}', elem.text):
        return True
    return False

tree = ElementTree.parse('data.xml')
serial = tree.find('DeviceData/Info/SerialNumber').text
engine = tree.find('DeviceData/Info/EngineVersion').text
media = tree.find('DeviceData/Info/MediaType').text

if proper_SN:
    serstr = "good"
else:
    serstr = "bad"

print "Found a %s serial number (%s), with engine %s and media %s" % (serstr, serial, engine, media)

我明白了

[mpenning@hotcoffee tmp]$ python parse.py 
Found a good serial number (154236), with engine 12.0.4.13 and media 100BaseT
[mpenning@hotcoffee tmp]$

使用XML解析模块,如lxml或{}(在Python stdlib中),而不是regex。然后,可以使用regex验证序列号。下面是一些使用ElementTree完成此操作的代码:

import re
import xml.etree.ElementTree

tree = xml.etree.ElementTree.XML(r'''
 <Data>
   <DeviceData>
       <Info>
        <SerialNumber>154236</SerialNumber>
        <Ethernet>Y</Ethernet>
        <Wireless>N</Wireless>
        <Mac>00:25:F6:25:K9</Mac>
       </Info>
   </DeviceData>
 </Data>
''')

serial = tree.find('DeviceData/Info/SerialNumber')
print serial.text

if re.match('\d{6}', serial.text.strip()):
    print 'OK'
else:
    print 'ERROR'

相关问题 更多 >