XSLT - 转换XML然后删除空父项和子项

时间:2014-09-09 00:42:20

标签: xml xslt

我有一个当前样式表,当应用于XML文件时,它会返回父项和子字段为空的字段。

我当前的XSLT看起来像这样

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
<root>
    <xsl:for-each select="pdml/packet">
        <PacketSRC id="{proto/field[@name='ip.src']/@show}">
            <PacketDST>
                <xsl:value-of select="proto/field[@name='ip.dst']/@show"/>
            </PacketDST>
            <PacketFLAG>
                <xsl:value-of select="proto/field[@name='tcp.flags']/@showname"/>
            </PacketFLAG>
            <PacketPORT> 
                <xsl:value-of select="proto/field[@name='tcp.dstport']/@show"/>
            </PacketPORT>
        </PacketSRC>
    </xsl:for-each>
</root>
</xsl:template>

</xsl:stylesheet>

当转换完成时,一些整个PacketSRC完全为空,而其他PacketSTRC则为空PacketPORT和PacketFLAG。

正确的输出如下:

<PacketSRC id="192.168.1.211">
  <PacketDST>192.168.1.254</PacketDST>
  <PacketFLAG>.... 0000 0000 0010 = Flags: 0x002 (SYN)</PacketFLAG>
  <PacketPORT>3306</PacketPORT>
</PacketSRC>

但由于访问的数据有些可能会显示为(两者都需要删除):

<PacketSRC id="">
  <PacketDST></PacketDST>
  <PacketFLAG></PacketFLAG>
  <PacketPORT></PacketPORT>
</PacketSRC>

OR

<PacketSRC id="192.168.1.211">
  <PacketDST>192.168.1.254</PacketDST>
  <PacketFLAG></PacketFLAG>
  <PacketPORT></PacketPORT>
</PacketSRC>

我已经查看了其他堆栈溢出答案以获取帮助,但我无法将它们与我的场景联系起来。所以我的问题是,如果任何值或字段为空,则将其从最终转换中删除。

1 个答案:

答案 0 :(得分:0)

  

有没有办法让它成为其中之一(packetDST,   packetFLAG,packetPORT)为空,然后移到下一个pdml / packet?

当然,只需创建一个围绕PacketSRC的测试:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/">
    <root>
      <xsl:for-each select="pdml/packet">
        <xsl:if test="proto[    field[@name='ip.dst']/@show
                            and field[@name='tcp.flags']/@showname
                            and field[@name='tcp.dstport']/@show
                            ]">
          <PacketSRC id="{proto/field[@name='ip.src']/@show">
            <PacketDST>
              <xsl:value-of select="proto/field[@name='ip.dst']/@show"/>
            </PacketDST>
            <PacketFLAG>
              <xsl:value-of select="proto/field[@name='tcp.flags']/@showname"/>
            </PacketFLAG>
            <PacketPORT> 
              <xsl:value-of select="proto/field[@name='tcp.dstport']/@show"/>
            </PacketPORT>
          </PacketSRC>
        </xsl:if>
      </xsl:for-each>
    </root>
  </xsl:template>

</xsl:stylesheet>

如果您希望在PacketSRC没有数据时省略@id,您也可以检查它:

    <xsl:if test="proto[    field[@name='ip.src']/@show
                        and field[@name='ip.dst']/@show
                        and field[@name='tcp.flags']/@showname
                        and field[@name='tcp.dstport']/@show
                        ]">