【发布时间】:2018-08-04 00:46:28
【问题描述】:
这个问题与RegEx find all XML tags 有关,但我正在尝试在 Windows PowerShell 中进行。
我有一个 XML 文件,其中包含许多不同的 XML 标签,而且文件很大,所以基本上我想使用 RegEx 解析文件并将所有标签的名称作为列表吐出。 XML 文档不是有效的 XML 文档,即使它包含 XML 标记和元素。所以使用 PowerShell 的 XML 函数是行不通的。尝试将其视为 XML 文档时出现许多错误,因此需要使用 RegEx。
我已经确定以下 RegEx 标识了标签(感谢上面提到的相关问题):(?<=<)([^\/]*?)((?= \/>)|(?=>))
这是我正在解析的文件的一个非常小的片段:
<data><bp_year /><bp_make>John Deere</bp_make><bp_model>650</bp_model><bp_price>3000.00</bp_price><bp_txtDayPhone>555-555-5555</bp_txtDayPhone><bp_bestPrice>3000.0000</bp_bestPrice><bp_txtComments>Best price available?</bp_txtComments><bp_url>https://www.example.com</bp_url></data>
<data><receiveOffers /><link>http://example.com/inventory.htm?id=2217405&used=1</link><itemName>2007 Yamaha RHINO 660</itemName></data>
<data><vehicleYear>2008</vehicleYear><vehicleMake>Buick</vehicleMake><vehicleModel>Enclave</vehicleModel><vehicleStyle>CX</vehicleStyle><vehicleInformation /><vehicleMileage /><phone>555-555-5555</phone><timeOfDay>Morning</timeOfDay><message /></data>
<data><mo_year>2009</mo_year><mo_make>Webasto</mo_make><mo_model>Air Top 2000</mo_model><mo_price /><mo_txtDayPhone>555-555-5555</mo_txtDayPhone><mo_txtOffer>700</mo_txtOffer><mo_txtTrade /><mo_txtComments /></data>
我真的没有太多使用 Powershell 的经验,但据我了解,你可以用它做 Grep 的东西。在互联网上搜索后,我找到了一些资源,通过使用 powershell Select-String 命令帮助我找到了我的解决方案。
我尝试了以下 powershell 命令,但它给了我太多反馈。我只想要一个主“匹配”列表。
Select-String -Path '.\dataXML stuff - Copy.xml'-Pattern "(?<=<)([^\/]*?)((?= \/>)|(?=>))" -AllMatches | Format-List -Property Matches
生成的输出样本:
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, address, city, region...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, address, city, region...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, vehicleYear, vehicleMake, vehicleModel...}
Matches : {data, mo_year, mo_make, mo_model...}
基本上,我想要这样的东西:
data
vehicleYear
vehicleMake
vehicleModel
address
city
region
mo_year
mo_make
mo_model
等等等等……
只返回和列出匹配的字符串,而不是告诉我在 XML 文件的每一行中匹配的内容。我更喜欢列表格式,因为这样我可以将它输入 Excel 并获得一个不同的标签名称列表,然后开始实际做我需要完成的事情,但是大量不同的 XML 标签并且不知道它们是什么让我起来。
也许 Select-String 不是最好的使用方法,但在找到这篇 Microsoft 帖子后,我觉得我已经接近我的解决方案了: https://social.technet.microsoft.com/Forums/windowsserver/en-US/d5bbd2fb-c8fa-43ed-b432-79ebfeee82ea/return-only-matches-from-selectstring?forum=winserverpowershell
基本上,这是根据我的需要修改的解决方案:
Gc 'C:\Documents\dataXML stuff - Copy.xml'|Select-String -Pattern "(?<=<)([^\/]*?)((?= \/>)|(?=>))"|foreach {$_.matches}|select value
它提供了所有 xml 标签的列表,就像我想要的一样,只是它只返回该行的第一个 XML 标签,所以我得到了很多:
data
data
data
但没有vehicleYear、vehicleMake、vehicleModel等,这将是该行的第2个或第3个或第11个xml标记。
【问题讨论】:
-
您是否有特定原因要使用 RegEx? PowerShell 支持 XML 看到这篇文章https://stackoverflow.com/questions/13732715/loop-through-xml-elements
-
没有具体原因。我认为 RegEx 将是一个好的开始,因为我什至不确定该文件是否是有效格式的 XML 文档。我现在正在看那个帖子,试图理解它。
-
就像我在帖子前面提到的那样,我根本不使用 PowerShell,在花了半小时阅读和重读该建议帖子之后,我无法让它为我吐出结果。我得到的只是错误。
-
我建议您使用HtmlAgilityPack 来解析您的文档。它也适用于 XML,最重要的是它可以很好地处理格式错误的文档。 RegEx 不能很好地替代真正的解析器;你不应该使用它。如果您的 XML 中缺少的只是
<?xml标记,那么只需添加它并使用内置类型。 -
briantist 的建议听起来不错。我完全同意正则表达式是第三方解析器的糟糕替代品。通常有一些你不会涵盖的边缘情况。我最初的假设是你有有效的 xml。但是你甚至不能确定它使正则表达式几乎不可能。并且使用第三方解析器很困难。纠正简单的无错误代码需要控制输入质量。
标签: regex xml powershell