使用Saxon 6.5.5和XLST进行转换无法正常工作

时间:2012-09-11 11:43:47

标签: xml stylesheet transform saxon

我想转换这个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"?>

有人知道这个问题吗?

谢谢, 麦克

2 个答案:

答案 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行,并且可以通过将公共代码片段移动到函数中来进一步降低。