问题
I want to transform this 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>
with this stylesheet
<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>
using Saxon 6.5.5. in a windows command line using this command:
java -jar C:\Saxon\Saxon6.5.5\saxon.jar -t -o calimero.xml 0.xml ets4_calimero_gui.xsl
The two files are in the correct directory and the output is the followed:
'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'
But the created calimero.xml only includes the following line:
<?xml version="1.0" encoding="iso-8859-1"?>
Does anybody know the problem?
Thanks, Mike
回答1:
Your XML input is in the xmlns:
xmlns="http://knx.org/xml/project/11"
Whereas your xslt is looking for
xmlns:b="http://knx.org/xml/project/10"
Looks like the schema version has been bumped up :)
回答2:
It's not related to your problem, though it is related to the fact that you seem to be fairly inexperienced in XSLT...
Firstly, if you are using Saxon then there really can't be any good reason for using XSLT 1.0. (Even less, "XSLT 1.1" which was an abandoned working draft that was never finished). You should move to a recent Saxon release (the current version is 9.4) and take advantage of all the benefits of using XSLT 2.0.
Secondly, even given the limitations of XSLT 1.0, this is really bad code:
(a) It's written completely monolithically - one template rule only
(b) it uses the preceding axis, which is very inefficient
(c) it uses xsl:attribute unnecessarily, which is very verbose
etc.
To give you a feel for the difference, the datapoint element and its attributes could be created like this (some of the improvements, but not all, depend on 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]}"
That's 51 lines of code down to 14, and it could come down further by moving the common code fragments into a function.
来源:https://stackoverflow.com/questions/12368937/transformation-with-saxon-6-5-5-and-xlst-does-not-work-correctly