我有一个相当复杂的xslt表使用模板将一个xml格式转换为另一个xml格式.但是,在生成的xml中,我需要排除所有空元素.怎么做的?
这就是基础xslt的样子:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:far="http://www.itella.com/fargo/fargogate/" xmlns:a="http://tempuri.org/XMLSchema.xsd" xmlns:p="http://tempuri.org/XMLSchema.xsd">
<xsl:import href="TransportCDMtoFDM_V0.6.xsl"/>
<xsl:import href="ConsignmentCDMtoFDM_V0.6.xsl"/>
<xsl:template match="/">
<InboundFargoMessage>
<EdiSender>
<xsl:value-of select="TransportInformationMessage/SenderId"/>
</EdiSender>
<EdiReceiver>
<xsl:value-of select="TransportInformationMessage/RecipientId"/>
</EdiReceiver>
<EdiSource>
<xsl:value-of select="TransportInformationMessage/Waybill/Parties/Consignor/Id"/>
</EdiSource>
<EdiDestination>FARGO</EdiDestination>
<Transportations>
<xsl:for-each select="TransportInformationMessage/TransportUnits/TransportUnit">
<xsl:call-template name="transport"/>
</xsl:for-each>
<xsl:for-each select="TransportInformationMessage/Waybill/TransportUnits/TransportUnit">
<xsl:call-template name="transport"/>
</xsl:for-each>
<xsl:for-each select="TransportInformationMessage/Waybill">
<EdiImportTransportationDTO>
<Consignments>
<xsl:for-each select="Shipments/Shipment">
<xsl:call-template name="consignment"/>
</xsl:for-each>
</Consignments>
<EdiTerminalDepartureTime>
<xsl:value-of select="DatesAndTimes/EstimatedDepartureDateTime"/>
<xsl:value-of select="DatesAndTimes/DepartureDateTime"/>
</EdiTerminalDepartureTime>
<EdiAgentTerminalArrivalDate>
<xsl:value-of select="DatesAndTimes/EstimatedArrivalDateTime"/>
<xsl:value-of select="DatesAndTimes/ArrivalDateTime"/>
</EdiAgentTerminalArrivalDate>
<EdiActivevehicle>
<xsl:value-of select="Vehicle/TransportShiftNumber"/>
</EdiActivevehicle>
<EdiConveyerZipCodeTown><xsl:text> </xsl:text></EdiConveyerZipCodeTown>
</EdiImportTransportationDTO>
</xsl:for-each>
</Transportations>
</InboundFargoMessage>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
需要添加什么,以便省略空元素?
例如,生成的xml中的代码段:
<?xml version="1.0" encoding="UTF-8"?>
<InboundFargoMessage xmlns:p="http://tempuri.org/XMLSchema.xsd"
xmlns:far="http://www.itella.com/fargo/fargogate/"
xmlns:a="http://tempuri.org/XMLSchema.xsd">
<EdiSender>XXXX</EdiSender>
<EdiReceiver>YYYY</EdiReceiver>
<EdiSource>TR/BAL/IST</EdiSource>
<EdiDestination>FARGO</EdiDestination>
<Transportations>
<EdiImportTransportationDTO>
<Consignments>
<EdiImportConsignmentDTO>
<ConsignmentLines>
<EdiImportConsignmentLineDTO>
<DangerousGoodsItems>
<EdiImportDangerGoodsItemDTO>
<EdiKolliTypeOuter/>
<EdiKolliTypeInner/>
<EdiTechnicalDescription/>
<EdiUNno/>
<EdiClass/>
<EdiDangerFactor/>
<EdiEmergencyTemperature/>
</EdiImportDangerGoodsItemDTO>
</DangerousGoodsItems>
<BarCodes>
<EdiImportConsignmentLineBarcodeDTO/>
</BarCodes>
<EdiNumberOfPieces>00000002</EdiNumberOfPieces>
<EdiGrossWeight>0.000</EdiGrossWeight>
<EdiHeight/>
<EdiWidth/>
<EdiLength/>
<EdiGoodsDescription/>
<EdiMarkingAndNumber/>
<EdiKolliType>road</EdiKolliType>
<EdiCbm/>
<EdiLdm/>
</EdiImportConsignmentLineDTO>
Run Code Online (Sandbox Code Playgroud)
这真的需要:
<?xml version="1.0" encoding="UTF-8"?>
<InboundFargoMessage xmlns:p="http://tempuri.org/XMLSchema.xsd"
xmlns:far="http://www.itella.com/fargo/fargogate/"
xmlns:a="http://tempuri.org/XMLSchema.xsd">
<EdiSender>XXXX</EdiSender>
<EdiReceiver>YYYY</EdiReceiver>
<EdiSource>TR/BAL/IST</EdiSource>
<EdiDestination>FARGO</EdiDestination>
<Transportations>
<EdiImportTransportationDTO>
<Consignments>
<EdiImportConsignmentDTO>
<ConsignmentLines>
<EdiImportConsignmentLineDTO>
<DangerousGoodsItems/>
<BarCodes/>
<EdiNumberOfPieces>00000002</EdiNumberOfPieces>
<EdiGrossWeight>0.000</EdiGrossWeight>
<EdiKolliType>road</EdiKolliType>
</EdiImportConsignmentLineDTO>
Run Code Online (Sandbox Code Playgroud)
换句话说:应该省略空元素.
Dim*_*hev 11
提供的(部分)XSLT代码很好地说明了XSLT反模式.尝试几乎总是避免使用<xsl:for-each>
.
下面是一个示例XML文档和一个转换,它复制除"空"元素之外的所有节点.这里的"空"我们指的是无子女,或者只有一个子空白子节点.
XML文档:
<a>
<b>
<c> </c>
<d/>
<e>1</e>
</b>
</a>
Run Code Online (Sandbox Code Playgroud)
转型:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[not(node())]
|
*[not(node()[2])
and
node()/self::text()
and
not(normalize-space())
]
"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
结果:
<a>
<b>
<e>1</e>
</b>
</a>
Run Code Online (Sandbox Code Playgroud)
请注意:
使用身份规则.
我们如何使用仅匹配"空"元素的模板覆盖标识规则.由于此模板不执行任何操作(根本没有任何主体),因此不会复制("删除")"空"元素.
使用和覆盖标识规则是最重要的XSLT设计模式.