3

所以我有两个 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 地址范围计算主机号。任何帮助将非常感激。

4

2 回答 2

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 号,而不是将它们作为参数传递。

于 2013-10-21T00:50:02.623 回答
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.
于 2013-10-21T00:50:53.633 回答