XSLT - IP地址范围减去查找主机数

时间:2013-10-20 21:27:03

标签: xml xslt

所以我有两个IP地址,一个endIP和startIP。必须根据IP地址范围计算主机数。

我测试了一个示例,即起始IP地址为192.168.2.188,包含88个主机。所以我的结束地址为192.168.3.19。但是,由于我的xml文件中没有88个主机的记录(因为它是自动生成的),我怎么想找到主机的数量?

所以我做了一个<xsl:value-of select="endIP - startIP"/>认为它至少会给我剩下的余数。但是,在解析之后,它返回了“NaN”。去图,因为它是多个小数。我对XSL并不是非常熟悉,所以这让人非常头疼。

我完全不知道如何根据IP地址范围计算主机号码。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

这样做的一种方法是将ip代码转换为整数,然后进行减法。当然,这会对子网中的主机数量做出一些隐含的假设。

对于此输入文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<HOSTS>
  <HOST ID="a" IP="192.168.2.188"/>
  <HOST ID="b" IP="192.168.3.19"/>
</HOSTS>

您可以使用以下XSLT文件

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="text"/>

  <xsl:template name="ip_to_number">
    <xsl:param name="ip"/>
    <xsl:variable name="ip1" select="substring-before($ip, '.')"/>
    <xsl:variable name="ip2" select="substring-before(substring-after($ip, concat($ip1, '.')), '.')"/>
    <xsl:variable name="ip3" select="substring-before(substring-after($ip, concat($ip1, '.', $ip2, '.')), '.')"/>
    <xsl:variable name="ip4" select="substring-after($ip, concat($ip1, '.', $ip2, '.', $ip3, '.'))"/>
    <xsl:value-of select="(((number($ip1) * 256) + number($ip2)) * 256 + number($ip3)) * 256 + number($ip4)"/>
  </xsl:template>

  <xsl:template match="/HOSTS">

    <xsl:variable name="number_a">
      <xsl:call-template name="ip_to_number">
        <xsl:with-param name="ip"><xsl:value-of select="HOST[@ID='a']/@IP"/></xsl:with-param>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="number_b">
      <xsl:call-template name="ip_to_number">
        <xsl:with-param name="ip"><xsl:value-of select="HOST[@ID='b']/@IP"/></xsl:with-param>
      </xsl:call-template>
    </xsl:variable>

    <xsl:text>Number of hosts: </xsl:text><xsl:value-of select="$number_b - $number_a + 1"/>

  </xsl:template>
</xsl:stylesheet>

结果是:

Number of hosts: 88

您可以编写另一个辅助模板来计算两个ip号之间的差异。此外,您可能希望更改模板,使其直接从源文档中提取IP编号,而不是将它们作为参数传递。

答案 1 :(得分:2)

此IP输入范围的输入XML文件:

<?xml version="1.0" encoding="utf-8"?>
<IPRanges>
  <IPRange start="192.168.2.188" end="192.168.3.19"/>
  <IPRange start="0.0.0.0" end="0.0.0.0"/>
  <IPRange start="0.0.0.1" end="0.0.0.0"/>
  <IPRange start="0.0.0.0" end="0.0.0.1"/>
  <IPRange start="0.0.0.0" end="1.1.1.1"/>
  <IPRange start="0.0.0.1" end="1.0.0.0"/>
  <IPRange start="0.0.0.0" end="255.255.255.255"/>
  <IPRange start="4.3.2.1" end="8.7.6.5"/>
  <IPRange start="0.0.1.0" end="0.0.0.1"/>
</IPRanges>

作为此XSLT转换的测试输入:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />

  <xsl:template name="CalcIpToDecimal">
    <xsl:param name="ip"/>
    <xsl:param name="pv"/>
    <xsl:variable name="ipCar" select="substring-before($ip, '.')"/>
    <xsl:variable name="ipCdr" select="substring-after($ip, '.')"/>
    <xsl:variable name="pvCar" select="substring-before($pv, '.')"/>
    <xsl:variable name="pvCdr" select="substring-after($pv, '.')"/>

    <xsl:variable name="valCar" select="$ipCar * $pvCar"/>
    <xsl:variable name="valCdr">
      <xsl:choose>
        <xsl:when test="$ipCdr eq ''">0</xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="CalcIpToDecimal">
            <xsl:with-param name="ip" select="$ipCdr"/>
            <xsl:with-param name="pv" select="$pvCdr"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:value-of select="$valCar + $valCdr"/>
  </xsl:template>

  <xsl:template name="IpToDecimal">
    <xsl:param name="ip"/>
    <xsl:call-template name="CalcIpToDecimal">
      <xsl:with-param name="ip" select="concat($ip, '.')"/>
      <xsl:with-param name="pv" select="'16777216.65536.256.1.'"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="HostCountInIPRange">
    <xsl:param name="start"/>
    <xsl:param name="end"/>
    <xsl:variable name="startDecimal">
      <xsl:call-template name="IpToDecimal">
        <xsl:with-param name="ip" select="$start"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="endDecimal">
      <xsl:call-template name="IpToDecimal">
        <xsl:with-param name="ip" select="$end"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="diff" select="$endDecimal - $startDecimal"/>
    <xsl:variable name="absDiff"
                  select="$diff*($diff >=0) - $diff*($diff &lt; 0)"/>
    <xsl:value-of select="$absDiff + 1"/>
  </xsl:template>

  <xsl:template match="/IPRanges/IPRange">
    <xsl:text>In the range of </xsl:text>
    <xsl:value-of select="@end"/>
    <xsl:text> to </xsl:text>
    <xsl:value-of select="@start"/>
    <xsl:text> there are </xsl:text>
    <xsl:call-template name="HostCountInIPRange">
      <xsl:with-param name="start" select="@start"/>
      <xsl:with-param name="end" select="@end"/>
    </xsl:call-template>
    <xsl:text> hosts.</xsl:text>
  </xsl:template>
</xsl:stylesheet>

产生此输出,显示给定范围内存在的唯一主机号码的数量:

  In the range of 192.168.3.19 to 192.168.2.188 there are 88 hosts.
  In the range of 0.0.0.0 to 0.0.0.0 there are 1 hosts.
  In the range of 0.0.0.0 to 0.0.0.1 there are 2 hosts.
  In the range of 0.0.0.1 to 0.0.0.0 there are 2 hosts.
  In the range of 1.1.1.1 to 0.0.0.0 there are 1.684301E7 hosts.
  In the range of 1.0.0.0 to 0.0.0.1 there are 1.6777216E7 hosts.
  In the range of 255.255.255.255 to 0.0.0.0 there are 4.294967296E9 hosts.
  In the range of 8.7.6.5 to 4.3.2.1 there are 6.7372037E7 hosts.
  In the range of 0.0.0.1 to 0.0.1.0 there are 256 hosts.