XSLT 1.0:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:key
name = "kInterfaceByName"
match = "interface"
use = "
substring-before(concat(
substring-before(concat(@name, ':'), ':'),
'.'), '.')
"
/>
<xsl:template match="i">
<xsl:copy>
<xsl:apply-templates mode="group" select="interface" />
</xsl:copy>
</xsl:template>
<xsl:template match="interface" mode="group">
<xsl:variable name="name" select="
substring-before(concat(
substring-before(concat(@name, ':'), ':'),
'.'), '.')
" />
<xsl:variable name="interfaces" select="key('kInterfaceByName', $name)" />
<!-- Muenchian step -->
<xsl:if test="generate-id()=generate-id($interfaces[1])">
<interface name="{$name}">
<xsl:apply-templates mode="unit" select="$interfaces" />
</interface>
</xsl:if>
</xsl:template>
<xsl:template match="interface" mode="unit">
<unit name="{@name}" />
</xsl:template>
</xsl:stylesheet>
применительно к
<i>
<interface name="Serial1/0"/>
<interface name="Serial2/0.0"/>
<interface name="Serial2/0.1"/>
<interface name="Serial3/0:0"/>
<interface name="Serial3/0:1"/>
</i>
Результаты в
<i>
<interface name="Serial1/0">
<unit name="Serial1/0" />
</interface>
<interface name="Serial2/0">
<unit name="Serial2/0.0" />
<unit name="Serial2/0.1" />
</interface>
<interface name="Serial3/0">
<unit name="Serial3/0:0" />
<unit name="Serial3/0:1" />
</interface>
</i>
Выражение XPath заменяет ваш шаблон getPhysicalInterfaceName
.
Это так, на примерах 'Serial2/0.0'
и 'Serial3/0:1'
:
- добавьте
':'
(=> 'Serial2/0.0:'
; 'Serial3/0:1:'
)
- принять все до первого
':'
(=> 'Serial2/0.0'
; 'Serial3/0'
)
- добавьте
'.'
(=> 'Serial2/0.0.'
; 'Serial3/0.'
)
- принять все до первого
'.'
(=> 'Serial2/0'
; 'Serial3/0'
)
РЕДАКТИРОВАТЬ: Упрощенное выражение XPath. Моя первая попытка сработала, но была более сложной:
concat(
substring-before(@name, '/'),
'/',
substring-before(
concat(
translate(substring-after(@name, '/'), '.', ':'), ':'
),
':'
)
)
На положительной стороне вышеприведенное выражение правильно обрабатывает двоеточия и точки в первой части имени, например, 'Some.Serial3/0:1'
. Короче нет. Если вы ожидаете точки в имени, используйте более длинное выражение. Объяснение этому есть в истории изменений этого поста .