我有这个XML片段:
<?xml version="1.0"?>
<FDT xmlns="x-schema:FDTMISPScanIdentSchema.xml" xmlns:mispident="x-schema:FDTMISPIdentSchema.xml"
xmlns:fdt="x-schema:FDTDataTypesSchema.xml">
<ScanIdentifications fdt:busCategory="D5FABA0D-8EE1-4AD0-8D2F-9B2D052C10C4"
resultState="final">
<ScanIdentification>
<IdBusProtocol mispident:busProtocol="MISP" />
<IdBusProtocolVersion
mispident:mispRevisionLevel="1" />
<IdManufacturer
mispident:manufacturerIdentificationCode="32" />
<IdAddress mispident:address="9600N81" />
<IdTypeID mispident:deviceTypeCode="60" />
<IdSerialNumber mispident:serial="0" />
<IdSoftwareRevision mispident:softwareRevision="1.0.4" />
<IdHardwareRevision />
</ScanIdentification>
</ScanIdentifications>
</FDT>
我使用这个XSLT来转换xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--
FDT: device identification transformation for MISP device identification xml files
-->
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://xsltsl.org/string"
xmlns:ident="x-schema:DTMIdentSchema.xml"
xmlns:fdt="x-schema:FDTDataTypesSchema.xml"
xmlns:scanident="x-schema:DTMScanIdentSchema.xml"
xmlns:devident="x-schema:DTMDeviceTypeIdentSchema.xml"
xmlns:mispident="x-schema:FDTMISPIdentSchema.xml"
xmlns:mispdevice="x-schema:FDTMISPDeviceTypeIdentSchema.xml"
xmlns:mispscan="x-schema:FDTMISPScanIdentSchema.xml" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!--
FDT: version of this file
-->
<xsl:variable name="FileVersion">
<xsl:number value="1.0"/>
</xsl:variable>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<!--
root: transform device or scan identification
-->
<xsl:template match="/">
<xsl:apply-templates select="//mispscan:ScanIdentifications"/>
<xsl:apply-templates select="//mispdevice:DeviceIdentifications"/>
</xsl:template>
<!--
MISP identification list
-->
<xsl:template match="mispdevice:DeviceIdentifications">
<xsl:text disable-output-escaping="yes"><?xml version="1.0"?>
<!-- This file is created by FDTMISPIdentTransformation.xsl after transformation of MISPDTMDeviceIdentificationInstance.xml -->
<FDT xmlns="x-schema:DTMDeviceTypeIdentSchema.xml"
xmlns:ident="x-schema:DTMIdentSchema.xml" xmlns:fdt="x-schema:FDTDataTypesSchema.xml" ></xsl:text>
<xsl:element name="DeviceIdentifications">
<xsl:apply-templates select="mispdevice:DeviceIdentification"/>
</xsl:element>
<xsl:text disable-output-escaping="yes"></FDT></xsl:text>
</xsl:template>
<!--
MISP catalog identifcation
-->
<xsl:template match="mispdevice:DeviceIdentification">
<xsl:element name="DeviceIdentification">
<xsl:attribute name="ident:idDTMSupportLevel">
<xsl:value-of select="@mispident:idDTMSupportLevel"/>
</xsl:attribute>
<xsl:apply-templates select="mispdevice:IdBusProtocol"/>
<xsl:apply-templates select="mispdevice:IdBusProtocolVersion"/>
<xsl:apply-templates select="mispdevice:IdManufacturer"/>
<xsl:apply-templates select="mispdevice:IdTypeID"/>
<xsl:apply-templates select="mispdevice:IdSoftwareRevision"/>
<xsl:apply-templates select="mispdevice:IdHardwareRevision"/>
<xsl:element name="IdValues">
<xsl:apply-templates select="mispdevice:DeviceCommandRevisionLevel"/>
<xsl:apply-templates select="mispdevice:DeviceFlag"/>
<xsl:apply-templates select="mispdevice:ManufacturerSpecificExtension"/>
</xsl:element>
</xsl:element>
</xsl:template>
<!--
MISP scan list
-->
<xsl:template match="mispscan:ScanIdentifications">
<xsl:text disable-output-escaping="yes"><?xml version="1.0"?>
<!-- This file is created by FDTMISPIdentTransformation.xsl after transformation of MISPDTMScanIdentificationInstance.xml --><FDT xmlns="x-schema:DTMScanIdentSchema.xml"
xmlns:ident="x-schema:DTMIdentSchema.xml" xmlns:fdt="x-schema:FDTDataTypesSchema.xml" ></xsl:text>
<xsl:element name="ScanIdentifications">
<xsl:attribute name="fdt:busCategory">
<xsl:value-of select="@fdt:busCategory"/>
</xsl:attribute>
<xsl:attribute name="resultState">
<xsl:value-of select="@resultState"/>
</xsl:attribute>
<xsl:apply-templates select="mispscan:ScanIdentification"/>
</xsl:element>
<xsl:text disable-output-escaping="yes"></FDT></xsl:text>
</xsl:template>
<!--
MISP scan identifcation
-->
<xsl:template match="mispscan:ScanIdentification">
<xsl:element name="ScanIdentification">
<xsl:apply-templates select="@configuredState" />
<xsl:apply-templates select="fdt:CommunicationError"/>
<xsl:apply-templates select="mispscan:IdBusProtocol"/>
<xsl:apply-templates select="mispscan:IdBusProtocolVersion"/>
<xsl:apply-templates select="mispscan:IdAddress"/>
<xsl:apply-templates select="mispscan:IdManufacturer"/>
<xsl:apply-templates select="mispscan:IdTypeID"/>
<xsl:apply-templates select="mispscan:IdSoftwareRevision"/>
<xsl:apply-templates select="mispscan:IdHardwareRevision"/>
<!-- don't get why this particular template doesn't work -->
<xsl:apply-templates select="mispscan:IdTag"/>
<!--
<xsl:element name="IdDeviceTag">
<xsl:attribute name="ident:value"/>
<xsl:attribute name="ident:protocolSpecificName">Tag</xsl:attribute>
</xsl:element>
-->
<xsl:apply-templates select="mispscan:IdSerialNumber"/>
<xsl:element name="IdValues">
<xsl:apply-templates select="mispscan:DeviceCommandRevisionLevel"/>
<xsl:apply-templates select="mispscan:DeviceFlag"/>
<xsl:apply-templates select="mispscan:ManufacturerSpecificExtension"/>
</xsl:element>
</xsl:element>
</xsl:template>
<!--
configured attribute
-->
<xsl:template match="@configuredState">
<xsl:attribute name="configuredState">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!--
MispScanIdentification: device tag, just copy
-->
<xsl:template match="mispscan:IdTag">
<xsl:element name="IdDeviceTag">
<xsl:attribute name="ident:value"/>
<xsl:attribute name="ident:protocolSpecificName">Tag</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MispScanIdentification: communicationError
-->
<xsl:template match="fdt:CommunicationError">
<xsl:element name="fdt:CommunicationError">
<xsl:attribute name="communicationError"><xsl:value-of select="@communicationError"/></xsl:attribute>
<xsl:attribute name="tag"><xsl:value-of select="@tag"/></xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MispScanIdentification: serialnumber
-->
<xsl:template match="mispscan:IdSerialNumber">
<xsl:element name="IdSerialNumber">
<xsl:attribute name="ident:value"><xsl:value-of select="@mispident:serial"/></xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">Device Identification Number</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MispScanIdentification: busaddress, just copy
-->
<xsl:template match="mispscan:IdAddress">
<xsl:element name="IdAddress">
<xsl:attribute name="ident:value"><xsl:value-of select="@mispident:address"/></xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">Port Configuration</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MispScanIdentification: CommandRevision, saved as protocol specific value
-->
<xsl:template match="mispdevice:DeviceCommandRevisionLevel">
<xsl:param name="value" select="@mispident:deviceCommandRevisionLevel"/>
<xsl:element name="IdValue">
<xsl:attribute name="ident:name">DeviceCommandRevisionLevel</xsl:attribute>
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">Device Revision Level</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:DeviceCommandRevisionLevel">
<xsl:element name="IdValue">
<xsl:attribute name="ident:name">DeviceCommandRevisionLevel</xsl:attribute>
<xsl:attribute name="ident:value">
<xsl:value-of select="@mispident:deviceCommandRevisionLevel"/>
</xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">Device Revision Level</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MispScanIdentification: DeviceFlag, saved as protocol specific value
-->
<xsl:template match="mispdevice:DeviceFlag">
<xsl:param name="value" select="@mispident:deviceFlag"/>
<xsl:element name="IdValue">
<xsl:attribute name="ident:name">DeviceFlag</xsl:attribute>
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">Flags</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:DeviceFlag">
<xsl:element name="IdValue">
<xsl:attribute name="ident:name">DeviceFlag</xsl:attribute>
<xsl:attribute name="ident:value">
<xsl:value-of select="@mispident:deviceFlag"/>
</xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">Flags</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
Misp Manufacaturer
-->
<xsl:template match="mispdevice:IdManufacturer">
<xsl:param name="manid" select="@mispident:manufacturerIdentificationCode"/>
<xsl:element name="IdManufacturer">
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$manid"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">Manufacturer Identification Code</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:IdManufacturer">
<xsl:element name="IdManufacturer">
<xsl:attribute name="ident:value">
<xsl:value-of select="@mispident:manufacturerIdentificationCode"/>
</xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">Manufacturer Identification Code</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
DevId:IdBusProtocol
-->
<xsl:template match="mispdevice:IdBusProtocol">
<xsl:param name="manid" select="@mispident:busProtocol"/>
<xsl:element name="IdBusProtocol">
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$manid"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">MISP</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:IdBusProtocol">
<xsl:element name="IdBusProtocol">
<xsl:attribute name="ident:value">
<xsl:value-of select="@mispident:busProtocol"/>
</xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">MISP</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
DevId:IdBusProtocolVersion
-->
<xsl:template match="mispdevice:IdBusProtocolVersion">
<xsl:param name="manid" select="@mispident:mispRevisionLevel"/>
<xsl:element name="IdBusProtocolVersion">
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$manid"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">MISP Revision</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:IdBusProtocolVersion">
<xsl:element name="IdBusProtocolVersion">
<xsl:attribute name="ident:value">
<xsl:value-of select="@mispident:mispRevisionLevel"/>
</xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">MISP Revision</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MISP device type
-->
<xsl:template match="mispdevice:IdTypeID">
<xsl:param name="value" select="@mispident:deviceTypeCode"/>
<xsl:param name="value_alt" select="@mispident:deviceTypeId"/>
<xsl:element name="IdTypeID">
<xsl:call-template name="genMatchChoose">
<xsl:with-param name="value" select="$value"/>
<xsl:with-param name="value_alt" select="$value_alt"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">Device Type Code</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:IdTypeID">
<xsl:param name="value" select="@mispident:deviceTypeCode"/>
<xsl:param name="value_alt" select="@mispident:deviceTypeId"/>
<xsl:element name="IdTypeID">
<xsl:call-template name="genMatchChoose">
<xsl:with-param name="value" select="$value"/>
<xsl:with-param name="value_alt" select="$value_alt"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">Device Type Code</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
MISP software revision
-->
<xsl:template match="mispdevice:IdSoftwareRevision">
<xsl:param name="value" select="@mispident:softwareRevision"/>
<xsl:element name="IdSoftwareRevision">
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">Software Revision</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:IdSoftwareRevision">
<xsl:param name="value" select="@mispident:softwareRevision"/>
<xsl:element name="IdSoftwareRevision">
<xsl:attribute name="ident:protocolSpecificName">Software Revision</xsl:attribute>
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<!--
MISP hardware revision
-->
<xsl:template match="mispdevice:IdHardwareRevision">
<xsl:param name="value" select="@mispident:hardwareRevision"/>
<xsl:element name="IdHardwareRevision">
<xsl:attribute name="ident:protocolSpecificName">Hardware Revision</xsl:attribute>
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:IdHardwareRevision">
<xsl:param name="value" select="@mispident:hardwareRevision"/>
<xsl:element name="IdHardwareRevision">
<xsl:attribute name="ident:protocolSpecificName">Hardware Revision</xsl:attribute>
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<!--
ManufacturerSpecificExtension
-->
<xsl:template match="mispdevice:ManufacturerSpecificExtension">
<xsl:param name="value" select="@mispident:manufacturerSpecificExtension"/>
<xsl:element name="IdValue">
<xsl:attribute name="ident:name">ManufacturerSpecificExtension</xsl:attribute>
<xsl:call-template name="genMatch">
<xsl:with-param name="value" select="$value"/>
</xsl:call-template>
<xsl:attribute name="ident:protocolSpecificName">ManufacturerSpecificExtension</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="mispscan:ManufacturerSpecificExtension">
<xsl:element name="IdValue">
<xsl:attribute name="ident:name">ManufacturerSpecificExtension</xsl:attribute>
<xsl:attribute name="ident:value">
<xsl:value-of select="@mispident:manufacturerSpecificExtension"/>
</xsl:attribute>
<xsl:attribute name="ident:protocolSpecificName">ManufacturerSpecificExtension</xsl:attribute>
</xsl:element>
</xsl:template>
<!--
generate matching information
-->
<xsl:template name="genMatch">
<xsl:param name="value"/>
<xsl:param name="empty"/>
<xsl:if test="$value!=$empty">
<xsl:attribute name="ident:value"><xsl:value-of select="$value"/></xsl:attribute>
</xsl:if>
<xsl:apply-templates select="mispident:RegExpr"/>
</xsl:template>
<!--
generate matching information by selecting one from two possible choices
-->
<xsl:template name="genMatchChoose">
<xsl:param name="value"/>
<xsl:param name="value_alt"/>
<xsl:param name="empty"/>
<xsl:choose>
<xsl:when test="$value!=$empty">
<xsl:attribute name="ident:value"><xsl:value-of select="$value"/></xsl:attribute>
</xsl:when>
<xsl:when test="$value_alt!=$empty">
<xsl:attribute name="ident:value"><xsl:value-of select="$value_alt"/></xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="mispident:RegExpr"/>
</xsl:template>
<!--
generate regular exressions
-->
<xsl:template match="mispident:RegExpr">
<!-- copy pattern info -->
<xsl:call-template name="genPattern">
<xsl:with-param name="match" select="@match"/>
<xsl:with-param name="nomatch" select="@nomatch"/>
</xsl:call-template>
</xsl:template>
<!--
generate pattern information
-->
<xsl:template name="genPattern">
<xsl:param name="match"/>
<xsl:param name="nomatch"/>
<xsl:param name="empty"/>
<xsl:choose>
<xsl:when test="$match!=$empty">
<xsl:element name="ident:RegExpr">
<xsl:attribute name="match"><xsl:value-of select="$match"/></xsl:attribute>
<xsl:if test="$nomatch!=$empty">
<xsl:attribute name="nomatch"><xsl:value-of select="$nomatch"/></xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:when>
<xsl:when test="$nomatch!=$empty">
<xsl:element name="ident:RegExpr">
<xsl:attribute name="nomatch"><xsl:value-of select="$nomatch"/></xsl:attribute>
<xsl:if test="$match!=$empty">
<xsl:attribute name="match"><xsl:value-of select="$match"/></xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:transform>
我得到了这个输出:
<?xml version="1.0"?>
<!-- This file is created by FDTMISPIdentTransformation.xsl after transformation
of MISPDTMScanIdentificationInstance.xml -->
<FDT xmlns="x-schema:DTMScanIdentSchema.xml" xmlns:ident="x-schema:DTMIdentSchema.xml"
xmlns:fdt="x-schema:FDTDataTypesSchema.xml">
<ScanIdentifications xmlns:fdt="x-schema:FDTDataTypesSchema.xml"
fdt:busCategory="D5FABA0D-8EE1-4AD0-8D2F-9B2D052C10C4" resultState="final">
<ScanIdentification>
<IdBusProtocol xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:value="MISP" ident:protocolSpecificName="MISP" />
<IdBusProtocolVersion xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:value="1" ident:protocolSpecificName="MISP Revision" />
<IdAddress xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:value="9600N81" ident:protocolSpecificName="Port Configuration" />
<IdManufacturer xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:value="32" ident:protocolSpecificName="Manufacturer Identification Code" />
<IdTypeID xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:value="60" ident:protocolSpecificName="Device Type Code" />
<IdSoftwareRevision xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:protocolSpecificName="Software Revision" ident:value="1.0.4" />
<IdHardwareRevision xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:protocolSpecificName="Hardware Revision" />
<IdSerialNumber xmlns:ident="x-schema:DTMIdentSchema.xml"
ident:value="0" ident:protocolSpecificName="Device Identification Number" />
<IdValues />
</ScanIdentification>
</ScanIdentifications>
</FDT>
我不明白为什么xsl:apply-templates匹配mispscan:IdTag没有被处理。我希望IdHardwareRevision之后的元素如此:
<IdDeviceTag xmlns:ident="x-schema:DTMIdentSchema.xml" ident:value="" ident:protocolSpecificName="Tag"/>
是因为模板:
<xsl:template match="mispscan:IdTag">
<xsl:element name="IdDeviceTag">
<xsl:attribute name="ident:value"/>
<xsl:attribute name="ident:protocolSpecificName">Tag</xsl:attribute>
</xsl:element>
</xsl:template>
是否对源文档或类似内容进行了任何匹配测试?我注意到,如果我只是在mispscan中生成元素:ScanIdentification模板就像这样
<xsl:template match="mispscan:ScanIdentification">
<xsl:element name="ScanIdentification">
<xsl:apply-templates select="@configuredState" />
<xsl:apply-templates select="fdt:CommunicationError"/>
<xsl:apply-templates select="mispscan:IdBusProtocol"/>
<xsl:apply-templates select="mispscan:IdBusProtocolVersion"/>
<xsl:apply-templates select="mispscan:IdAddress"/>
<xsl:apply-templates select="mispscan:IdManufacturer"/>
<xsl:apply-templates select="mispscan:IdTypeID"/>
<xsl:apply-templates select="mispscan:IdSoftwareRevision"/>
<xsl:apply-templates select="mispscan:IdHardwareRevision"/>
<!-- don't get why this particular template doesn't work
<xsl:apply-templates select="mispscan:IdTag"/>
-->
<xsl:element name="IdDeviceTag">
<xsl:attribute name="ident:value"/>
<xsl:attribute name="ident:protocolSpecificName">Tag</xsl:attribute>
</xsl:element>
<xsl:apply-templates select="mispscan:IdSerialNumber"/>
<xsl:element name="IdValues">
<xsl:apply-templates select="mispscan:DeviceCommandRevisionLevel"/>
<xsl:apply-templates select="mispscan:DeviceFlag"/>
<xsl:apply-templates select="mispscan:ManufacturerSpecificExtension"/>
</xsl:element>
</xsl:element>
</xsl:template>
它按照我期望的方式工作。
我想这很好,但我想知道为什么mispscan:IdTag模板没有得到处理。
答案 0 :(得分:0)
通常,有几个原因导致可能无法评估与特定元素匹配的模板:
样式表中没有xsl:apply-templates会导致模板匹配发生在相关元素上。在许多使用传统XSLT样式编写的样式表中,这归结为:与父元素匹配的模板不包含任何xsl:apply-templates指令。
还有另一个优先级较高的模板与相关元素相匹配。
输入中没有与模板匹配的元素。
由于您显示的输入中没有mispscan:IdTag元素,因此在这种情况下看起来好像是第三个:您的mispscan模板:IdTag未被评估,因为它与输入。