此问题与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命令,但它给了我太多反馈。我只想要一个大师&#34;匹配&#34;列表。
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并不是最好用的方法,但我觉得在找到这篇微软帖子之后我已经接近我的解决方案了: 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标签。
答案 0 :(得分:2)
至于......
就像我之前在帖子中提到的那样,我根本不使用PowerShell
阅读是一件好事,但看到它在行动中会更好。有许多免费的视频资源可以从一开始就查看PowerShell,以及大量的参考资料。然后是要利用的MS TechNet虚拟实验室。
请参阅此帖子,了解为学习PowerShell提供一些途径的人。
有没有人有教过别人权力的经验?
https://www.reddit.com/r/PowerShell/comments/7oir35/help_with_teaching_others_powershell
当然可以使用RegEx来完成它,但最好是本地处理它。
在PowerShell中,XML是一个大问题;和JSON一样。所有帮助文件只是一个XML文件。有一些bulit-in cmdlet来处理它。
# Get parameters, examples, full and Online help for a cmdlet or function
Get-Command -Name '*xml*' | Format-Table -AutoSize
(Get-Command -Name Select-Xml).Parameters
Get-help -Name Select-Xml -Examples
Get-help -Name Select-Xml -Full
Get-help -Name Select-Xml -Online
Get-Help about_*
# Find all cmdlets / functions with a target parameter
Get-Help * -Parameter xml
# All Help topics locations
explorer "$pshome\$($Host.CurrentCulture.Name)"
许多网站都提供有关处理它的文章。
PowerShell数据基础知识:XML
要掌握PowerShell,您必须知道如何使用XML。 XML是一种重要的数据交换格式,因为它仍然是确保保留对象数据的最可靠方法。幸运的是,正如Michael Sorens演示的那样,PowerShell使这一切变得简单。
https://www.red-gate.com/simple-talk/sysadmin/powershell/powershell-data-basics-xml
将XML转换为PowerShell PSObject
最近,我正在研究一些代码(当然)并且需要将一些XML转换为PowerShell PSObjects。我在那里找到了一些片段,但这不是我练习这个练习所需的方式。在这种情况下,我正在从Plex转换XML元数据。
https://consciouscipher.wordpress.com/2015/06/05/converting-xml-to-powershell-psobject
掌握PowerShell中的日常XML任务
PowerShell具有出色的XML支持。一开始并不是很明显,但是在PowerShellMagazine.com的朋友们的帮助下,您很快就会解决日常的XML任务 - 甚至是非常复杂的任务。
因此,让我们看一下如何使用非常简单的PowerShell代码来完成以前在PowerShell之前的时代那么令人费解的事情。
http://www.powershellmagazine.com/2013/08/19/mastering-everyday-xml-tasks-in-powershell
对于所有意图和目的,如果我只为您的样本选择一行,并使用.Net xml命名空间执行此操作...
($MyXmlData = [xml]'<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
----
data
你得到这样的结果......
$MyXmlData.data
bp_year :
bp_make : John Deere
bp_model : 650
bp_price : 3000.00
bp_txtDayPhone : 555-555-5555
bp_bestPrice : 3000.0000
bp_txtComments : Best price available?
bp_url : https://www.example.com
使用intellisene /自动完成节点/元素...
$MyXmlData.data.bp_year
另一种观点......
$MyXmlData.data | Format-Table -AutoSize
bp_year bp_make bp_model bp_price bp_txtDayPhone bp_bestPrice bp_txtComments bp_url
------- ------- -------- -------- -------------- ------------ -------------- ------
John Deere 650 3000.00 555-555-5555 3000.0000 Best price available? https://www.example.com
然后,只需设置标签/名称
$MyXmlData.data.ChildNodes.Name
bp_year
bp_make
bp_model
bp_price
bp_txtDayPhone
bp_bestPrice
bp_txtComments
bp_url
所以,配备上述方法/说明。只需循环浏览您的文件即可获得您所追求的一切。
因此,只需将您的样本转储到一个没有更改的文件中,就可以做到这一点。
$MyXmlData = (Get-Content -Path 'D:\Scripts\MyXmlData.xml')
$MyXmlData | Format-List -Force
ForEach($DataRow in $MyXmlData)
{
($DataObject = [xml]$DataRow).Data | Format-Table -AutoSize
}
bp_year bp_make bp_model bp_price bp_txtDayPhone bp_bestPrice bp_txtComments bp_url
------- ------- -------- -------- -------------- ------------ -------------- ------
John Deere 650 3000.00 555-555-5555 3000.0000 Best price available? https://www.example.com
receiveOffers link itemName
------------- ---- --------
http://example.com/inventory.htm?id=2217405&used=1 2007 Yamaha RHINO 660
vehicleYear vehicleMake vehicleModel vehicleStyle vehicleInformation vehicleMileage phone timeOfDay message
----------- ----------- ------------ ------------ ------------------ -------------- ----- --------- -------
2008 Buick Enclave CX 555-555-5555 Morning
mo_year mo_make mo_model mo_price mo_txtDayPhone mo_txtOffer mo_txtTrade mo_txtComments
------- ------- -------- -------- -------------- ----------- ----------- --------------
2009 Webasto Air Top 2000 555-555-5555 700
ForEach($DataRow in $MyXmlData)
{
($DataObject = [xml]$DataRow).Data.ChildNodes.Name
}
bp_year
bp_make
bp_model
bp_price
bp_txtDayPhone
bp_bestPrice
bp_txtComments
bp_url
receiveOffers
link
itemName
vehicleYear
vehicleMake
vehicleModel
vehicleStyle
vehicleInformation
vehicleMileage
phone
timeOfDay
message
mo_year
mo_make
mo_model
mo_price
mo_txtDayPhone
mo_txtOffer
mo_txtTrade
mo_txtComments
但是,请注意,这不是唯一的方法。