我想转换这个xml:
<?xml version="1.0" encoding="utf-8"?>
<KNX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" CreatedBy="ETS4" ToolVersion="ETS 4.1.2 (Build 3013)" xmlns="http://knx.org/xml/project/11">
<Project Id="P-065C">
<Installations>
<Installation InstallationId="0" Name="" BCUKey="4294967295" DefaultLine="P-065C-0_L-2" IPRoutingMulticastAddress="224.0.23.12" SplitType="None" CompletionStatus="Undefined">
<Topology>
<Area Id="P-065C-0_A-0" Name="Backbone Bereich" Address="0" CompletionStatus="Undefined">
<Line Id="P-065C-0_L-0" Name="Bereichslinie" Address="0" MediumTypeRefId="MT-5" DomainAddress="0" DomainAddressIsChecked="0" CompletionStatus="Undefined" IPRoutingMulticastAddress="224.0.23.12" MulticastTTL="16" />
</Area>
<Area Id="P-065C-0_A-1" Name="Neuer Bereich" Address="1" CompletionStatus="Undefined">
<Line Id="P-065C-0_L-1" Name="Hauptlinie" Address="0" MediumTypeRefId="MT-5" DomainAddress="0" DomainAddressIsChecked="0" CompletionStatus="Undefined" IPRoutingMulticastAddress="224.0.23.12" MulticastTTL="16" />
<Line Id="P-065C-0_L-2" Name="Neue Linie" Address="1" MediumTypeRefId="MT-0" DomainAddress="0" DomainAddressIsChecked="0" CompletionStatus="Undefined" IPRoutingMulticastAddress="224.0.23.12" MulticastTTL="16">
<DeviceInstance Id="P-065C-0_DI-1" ProductRefId="M-0002_H-2CDG.20110.20085.20R0011-1_P-2CDG.20110.20085.20R0011" Hardware2ProgramRefId="M-0002_H-2CDG.20110.20085.20R0011-1_HP" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0" />
<DeviceInstance Id="P-065C-0_DI-2" ProductRefId="M-0002_H-2CDG110061R0011-1_P-2CDG.20110.20061.20R0011" Hardware2ProgramRefId="M-0002_H-2CDG110061R0011-1_HP-A035-10-377F" Address="0" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0" />
<DeviceInstance Id="P-065C-0_DI-3" ProductRefId="M-0008_H-8.20.2F.2F.2018500-1-O0001_P-185.2000" Hardware2ProgramRefId="M-0008_H-8.20.2F.2F.2018500-1-O0001_HP-1058-01-D423-O0001" Address="1" LastModified="2012-09-07T14:20:33" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0">
<ComObjectInstanceRefs>
<ComObjectInstanceRef RefId="M-0008_A-1058-01-D423-O0001_O-0_R-5" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-1" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0008_A-1058-01-D423-O0001_O-1_R-11" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-1" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0008_A-1058-01-D423-O0001_O-2_R-23" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-2" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0008_A-1058-01-D423-O0001_O-3_R-26" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-2" />
</Connectors>
</ComObjectInstanceRef>
</ComObjectInstanceRefs>
</DeviceInstance>
<DeviceInstance Id="P-065C-0_DI-6" ProductRefId="M-0048_H-1319201-2_P-1319201" Hardware2ProgramRefId="M-0048_H-1319201-2_HP-131C-12-4C9E" Address="2" LastModified="2012-09-07T12:16:26" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0">
<ComObjectInstanceRefs>
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-12_R-209" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-13_R-13" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-14_R-14" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-15_R-15" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-16_R-63" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-17_R-17" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-4_R-68" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-40_R-215" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-1_R-2" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-3" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-0_R-1" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-3" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-7_R-8" IsActive="1" />
<ComObjectInstanceRef RefId="M-0048_A-131C-12-4C9E_O-8_R-122" IsActive="1" />
</ComObjectInstanceRefs>
</DeviceInstance>
<DeviceInstance Id="P-065C-0_DI-5" ProductRefId="M-0008_H-8.20.2F.2F.20570.2000-1_P-570.2000" Hardware2ProgramRefId="M-0008_H-8.20.2F.2F.20570.2000-1_HP" Address="3" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0" />
<DeviceInstance Id="P-065C-0_DI-7" ProductRefId="M-0007_H-2CDG.20110.20079.20R0011-1-O0002_P-6197.2F22" Hardware2ProgramRefId="M-0007_H-2CDG.20110.20079.20R0011-1-O0002_HP-A043-12-5DB8-O0002" Address="4" LastModified="2012-09-07T14:20:45" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0">
<ComObjectInstanceRefs>
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-10_R-2438" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-1" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-12_R-2319" IsActive="1" />
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-13_R-2443" IsActive="1" />
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-34_R-2433" IsActive="1" />
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-35_R-2440" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-2" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-38_R-2450" IsActive="1" />
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-59_R-2432" IsActive="1" />
<ComObjectInstanceRef RefId="M-0007_A-A043-12-5DB8-O0002_O-37_R-2316" DatapointType="DPST-3-7" IsActive="1" />
</ComObjectInstanceRefs>
</DeviceInstance>
<DeviceInstance Id="P-065C-0_DI-8" ProductRefId="M-0008_H-8.20.2F.2F.20880.20xx-1_P-880.20xx" Hardware2ProgramRefId="M-0008_H-8.20.2F.2F.20880.20xx-1_HP-A003-01-737E" Address="5" LastModified="2012-09-07T12:16:43" CompletionStatus="Undefined" IndividualAddressLoaded="0" ApplicationProgramLoaded="0" ParametersLoaded="0" CommunicationPartLoaded="0" MediumConfigLoaded="0" IsCommunicationObjectVisibilityCalculated="1" Broken="0">
<ComObjectInstanceRefs>
<ComObjectInstanceRef RefId="M-0008_A-A003-01-737E_O-0_R-0" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-4" />
</Connectors>
</ComObjectInstanceRef>
<ComObjectInstanceRef RefId="M-0008_A-A003-01-737E_O-1_R-1" IsActive="1" />
<ComObjectInstanceRef RefId="M-0008_A-A003-01-737E_O-2_R-2" IsActive="1">
<Connectors>
<Send GroupAddressRefId="P-065C-0_GA-4" />
</Connectors>
</ComObjectInstanceRef>
</ComObjectInstanceRefs>
</DeviceInstance>
</Line>
</Area>
</Topology>
<Buildings>
<BuildingPart Id="P-065C-0_BP-0" Name="Hauptgebäude" Type="Building" CompletionStatus="Undefined">
<BuildingPart Id="P-065C-0_BP-1" Name="Vordergebäude" Type="BuildingPart" CompletionStatus="Undefined" />
<BuildingPart Id="P-065C-0_BP-2" Name="Rückgebäude" Type="BuildingPart" CompletionStatus="Undefined">
<BuildingPart Id="P-065C-0_BP-3" Name="Erdgeschoss" Type="Floor" CompletionStatus="Undefined" />
<BuildingPart Id="P-065C-0_BP-4" Name="1.Etage" Type="Floor" CompletionStatus="Undefined">
<BuildingPart Id="P-065C-0_BP-5" Name="Küche" Type="Room" CompletionStatus="Undefined" />
<BuildingPart Id="P-065C-0_BP-6" Name="Büro Poolfahrzeuge" Type="Room" CompletionStatus="Undefined" />
<BuildingPart Id="P-065C-0_BP-7" Name="Büro Studenten" Type="Room" CompletionStatus="Undefined">
<DeviceInstanceRef RefId="P-065C-0_DI-1" />
<DeviceInstanceRef RefId="P-065C-0_DI-2" />
<DeviceInstanceRef RefId="P-065C-0_DI-5" />
<DeviceInstanceRef RefId="P-065C-0_DI-6" />
<DeviceInstanceRef RefId="P-065C-0_DI-8" />
<DeviceInstanceRef RefId="P-065C-0_DI-3" />
<DeviceInstanceRef RefId="P-065C-0_DI-7" />
</BuildingPart>
</BuildingPart>
</BuildingPart>
</BuildingPart>
</Buildings>
<GroupAddresses>
<GroupRanges>
<GroupRange Id="P-065C-0_GR-1" Name="Zentralfunktionen" RangeStart="1" RangeEnd="2047">
<GroupRange Id="P-065C-0_GR-3" Name="Sensorwerte auslesen" RangeStart="256" RangeEnd="511">
<GroupAddress Id="P-065C-0_GA-3" Address="256" Name="Helligkeitssensor" />
<GroupAddress Id="P-065C-0_GA-4" Address="257" Name="Bewegungsmelder" />
</GroupRange>
<GroupRange Id="P-065C-0_GR-2" Name="Licht steuern" RangeStart="1" RangeEnd="255">
<GroupAddress Id="P-065C-0_GA-1" Address="1" Name="Glühbirne 1" />
<GroupAddress Id="P-065C-0_GA-2" Address="2" Name="Glühbirne 2" />
</GroupRange>
</GroupRange>
</GroupRanges>
</GroupAddresses>
</Installation>
</Installations>
</Project>
</KNX>
使用此样式表
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>
<xsl:template match="/" xmlns:b="http://knx.org/xml/project/10">
<xsl:for-each select="b:KNX/b:Project/b:Installations/b:Installation/b:Topology">
<datapoints>
<xsl:for-each select="b:Area/b:Line/b:DeviceInstance/b:ComObjectInstanceRefs/b:ComObjectInstanceRef">
<xsl:sort select="b:Connectors/b:Send/@GroupAddressRefId"/>
<xsl:if test="not(preceding::b:Connectors/b:Send/@GroupAddressRefId = current()/b:Connectors/b:Send/@GroupAddressRefId)">
<xsl:for-each select="b:Connectors">
<xsl:variable name="verz" select="document(concat(substring(../@RefId,0,7),'/',substring-before(../@RefId, '_O'), '.xml'))/b:KNX/b:ManufacturerData/b:Manufacturer/b:ApplicationPrograms/b:ApplicationProgram/b:Static/b:ComObjectTable/b:ComObject[@Id = ../../b:ComObjectRefs/b:ComObjectRef[@Id = current()/../@RefId]/@RefId]" />
<xsl:variable name="grosse">
<xsl:choose>
<xsl:when test="substring-after($verz/@ObjectSize,' ') = 'Bytes'">
<xsl:value-of select="substring-before($verz/@ObjectSize,' ')*8" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($verz/@ObjectSize,' ')" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="master" select="document('knx_master.xml')/b:KNX/b:MasterData/b:DatapointTypes/b:DatapointType[@SizeInBit = $grosse]" />
<xsl:variable name="master2" select="document('knx_master.xml')/b:KNX/b:MasterData/b:DatapointTypes/b:DatapointType/b:DatapointSubtypes/b:DatapointSubtype[@Id = current()/../@DatapointType]" />
<xsl:variable name="master3" select="document('knx_master.xml')/b:KNX/b:MasterData/b:DatapointTypes/b:DatapointType[@Id = current()/../@DatapointType]" />
<xsl:variable name="graddress" select="/b:KNX/b:Project/b:Installations/b:Installation/b:GroupAddresses/b:GroupRanges/b:GroupRange/b:GroupRange" />
<datapoint>
<xsl:attribute name="stateBased">
<xsl:value-of select="'true'"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="$verz/@Name"/>
</xsl:attribute>
<xsl:attribute name="mainNumber">
<xsl:choose>
<xsl:when test="../@DatapointType != ''">
<xsl:choose>
<xsl:when test="string-length(../@DatapointType) > 5">
<xsl:value-of select="$master2/../../@Number"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$master3/@Number"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$master/@Number"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="dptID">
<xsl:choose>
<xsl:when test="../@DatapointType != ''">
<xsl:choose>
<xsl:when test="string-length(../@DatapointType) > 5">
<xsl:value-of select="concat($master2/../../@Number, '.',format-number($master2/@Number, '000') )"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($master3/@Number, '.001')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($master/@Number,'.',format-number($master/b:DatapointSubtypes/b:DatapointSubtype/@Number, '000'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="priority">
<xsl:choose>
<xsl:when test="../@Priority">
<xsl:value-of select="../@Priority"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$verz/@Priority"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:for-each select="b:Send">
<knxAddress type="group">
<xsl:value-of select="$graddress/b:GroupAddress[@Id = current()/@GroupAddressRefId]/@Address"/>
</knxAddress>
</xsl:for-each>
<expiration timeout="0"/>
<xsl:choose>
<xsl:when test="b:Receive">
<xsl:for-each select="b:Receive">
<updatingAddresses>
<xsl:value-of select="$graddress/b:GroupAddress[@Id = current()/@GroupAddressRefId]/@Address"/>
</updatingAddresses>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<updatingAddresses>
<xsl:text> </xsl:text>
</updatingAddresses>
</xsl:otherwise>
</xsl:choose>
<invalidatingAddresses>
<xsl:text> </xsl:text>
</invalidatingAddresses>
</datapoint>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</datapoints>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
使用Saxon 6.5.5。在使用此命令的Windows命令行中:
java -jar C:\Saxon\Saxon6.5.5\saxon.jar -t -o calimero.xml 0.xml ets4_calimero_gui.xsl
这两个文件位于正确的目录中,输出如下:
'SAXON 6.5.5 from Michael Kay
Java version 1.6.0_31
Loading com.icl.saxon.sort.Compare_d
Preparation time: 225 milliseconds
Processing file:/C:/Saxon/Saxon6.5.5
Building tree for file:/C:/Saxon/Sax
tree.TinyBuilder
Tree built in 33 milliseconds
Loading java.net.URI
Execution time: 100 milliseconds'
但是创建的calimero.xml只包含以下行:
<?xml version="1.0" encoding="iso-8859-1"?>
有人知道这个问题吗?
谢谢, 麦克
答案 0 :(得分:2)
您的XML输入位于xmlns:
xmlns="http://knx.org/xml/project/11"
而你的xslt正在寻找
xmlns:b="http://knx.org/xml/project/10"
看起来架构版本已经被提升了:)
答案 1 :(得分:1)
这与你的问题没有关系,虽然这与你在XSLT中似乎缺乏经验这一事实有关...
首先,如果您使用Saxon,那么使用XSLT 1.0确实没有任何合理的理由。 (甚至更少,“XSLT 1.1”这是一个废弃的工作草案,从未完成)。您应该转到Saxon最新版本(当前版本为9.4)并充分利用使用XSLT 2.0的所有好处。
其次,即使考虑到XSLT 1.0的限制,这也是非常糟糕的代码:
(a)它完全是单一的 - 只有一个模板规则
(b)它使用前一轴,这是非常低效的
(c)它不必要地使用xsl:attribute,这是非常详细的
等
为了让您了解差异,可以像这样创建datapoint元素及其属性(一些改进,但不是全部,取决于XSLT 2.0):
<datapoint
stateBased="true"
name="{$verz/@Name}"
mainNumber="{if (../@DatapointType != '')
then if(string-length(../@DatapointType) gt 5)
then $master2/../../@Number
else $master3/@Number
else $master/@Number}"
dptId="{if (../@DatapointType != '')
then if (string-length(../@DatapointType) gt 5)
then concat($master2/../../@Number, '.',format-number($master2/@Number, '000')
else concat($master3/@Number, '.001')
else concat($master/@Number,'.',format-number($master/b:DatapointSubtypes/b:DatapointSubtype/@Number, '000'))}"
priority="{(../@Priority, $verz/@Priority)[1]}"
这是51行代码,直到14行,并且可以通过将公共代码片段移动到函数中来进一步降低。