使用XSLT将XML循环到单个Excel单元格中

希望转换(XSL,XSLT到Excel):

<NessusClientData_v2> <Report name="FAKEDB" xmlns:cm="http://www.nessus.org/cm"> <ReportHost name="192.168.1.1"> <HostProperties> <tag name="operating-system">Microsoft Windows Server 2008 R2 Enterprise Service Pack 1</tag> <tag name="host-fqdn">FAKEDB</tag> </HostProperties> <ReportItem port="0" svc_name="general" protocol="tcp" severity="0" pluginID="19506" pluginName="Nessus Scan Information" pluginFamily="Settings"> </ReportItem> <ReportItem port="1122" svc_name="availant-mgr?" protocol="tcp" severity="0" pluginID="11219" pluginName="Nessus SYN scanner" pluginFamily="Port scanners"> </ReportItem> <ReportItem port="1122" svc_name="ssh" protocol="tcp" severity="2" pluginID="10882" pluginName="SSH Protocol Version 1 Session Key Retrieval" pluginFamily="General"> </ReportItem> </Report> <Report name="FAKEAPP" xmlns:cm="http://www.nessus.org/cm"> <ReportHost name="192.168.1.2"> <HostProperties> <tag name="operating-system">Microsoft Windows Server 2008 R2 Enterprise Service Pack 1</tag> <tag name="host-fqdn">FAKEDB</tag> </HostProperties> <ReportItem port="1122" svc_name="availant-mgr?" protocol="tcp" severity="0" pluginID="11219" pluginName="Nessus SYN scanner" pluginFamily="Port scanners"> </ReportItem> <ReportItem port="1122" svc_name="ssh" protocol="tcp" severity="2" pluginID="10882" pluginName="SSH Protocol Version 1 Session Key Retrieval" pluginFamily="General"> </ReportItem> <ReportItem port="47001" svc_name="www" protocol="tcp" severity="0" pluginID="11219" pluginName="Nessus SYN scanner" pluginFamily="Port scanners"> </ReportItem> <ReportItem port="49152" svc_name="dce-rpc" protocol="tcp" severity="0" pluginID="11219" pluginName="Nessus SYN scanner" pluginFamily="Port scanners"> </ReportItem> <ReportItem port="0" svc_name="general" protocol="udp" severity="0" pluginID="10287" pluginName="Traceroute Information" pluginFamily="General"> </ReportItem> <ReportItem port="139" svc_name="smb" protocol="tcp" severity="0" pluginID="11011" pluginName="Microsoft Windows SMB Service Detection" pluginFamily="Windows"> </ReportItem> </Report> 

像这样的东西:

 Port Service FQDN ==== ======== ===== 1122 availant-mgr? FAKEDB, FAKEAPP 1122 SSH FAKEDB, FAKEAPP 47001 www FAKEAPP 

我可以做直接的转换,但没有像这样在一个单元格中添加多个节点块。 我使用“generate-id”调用了一个体面的样本,但我无法将其分解到单独的列中,也无法获得所需的逻辑:

  1. 只有当pluginID = 11219时才返回
  2. 当port&svc_name不相同时,创build一个新行。

任何人都可以指点我会很好。

谢谢。 肖恩。

考虑使用Muenchian方法 ,它可以使用定义的键通过@portsvc_nameReportItem节点svc_name

 <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:cm="http://www.nessus.org/cm"> <xsl:output version="1.0" encoding="UTF-8" indent="yes" /> <xsl:strip-space elements="*"/> <xsl:key name="portsrvkey" match="ReportItem" use="concat(@port,@svc_name)" /> <xsl:template match="/"> <root> <xsl:apply-templates select="*"/> </root> </xsl:template> <xsl:template match="ReportHost"> <xsl:apply-templates select="ReportItem[generate-id()= generate-id(key('portsrvkey', concat(@port,@svc_name))[1])]"/> </xsl:template> <xsl:template match="ReportItem[generate-id()= generate-id(key('portsrvkey', concat(@port,@svc_name))[1])]"> <xsl:variable name="key" select="key('portsrvkey', concat(@port,@svc_name))"/> <xsl:copy> <por><xsl:value-of select="@port"/></por> <service><xsl:value-of select="@svc_name"/></service> <report><xsl:value-of select="$key/ancestor::Report/@name"/></report> </xsl:copy> </xsl:template> </xsl:transform> 

XML输出

 <?xml version="1.0" encoding="UTF-8"?> <root xmlns:cm="http://www.nessus.org/cm"> <ReportItem> <por>0</por> <service>general</service> <report>FAKEDB FAKEAPP</report> </ReportItem> <ReportItem> <por>1122</por> <service>availant-mgr?</service> <report>FAKEDB FAKEAPP</report> </ReportItem> <ReportItem> <por>1122</por> <service>ssh</service> <report>FAKEDB FAKEAPP</report> </ReportItem> <ReportItem> <por>47001</por> <service>www</service> <report>FAKEAPP</report> </ReportItem> <ReportItem> <por>49152</por> <service>dce-rpc</service> <report>FAKEAPP</report> </ReportItem> <ReportItem> <por>139</por> <service>smb</service> <report>FAKEAPP</report> </ReportItem> </root> 

然后,您可以使用Excel的Workbooks.OpenXML方法导入电子表格:

 Workbooks.OpenXML "C:\Path\To\Transformed\Output.xml", , xlXmlLoadImportToList