我有一个xml,看起来像:
<RestrictedTicket>abc</RestrictedTicket>
<FlightDetails1>
<CouponNumber>1</CouponNumber>
<ServiceClass>F</ServiceClass>
<CarrierCode>SL</CarrierCode>
</FlightDetails1>
<FlightDetails2>
<CouponNumber>2</CouponNumber>
<ServiceClass>G</ServiceClass>
<CarrierCode>KL</CarrierCode>
</FlightDetails2>
我使用的XSLT看起来像:
<RestrictedTicket>
<xsl:value-of select="RestrictedTicket" />
</RestrictedTicket>
<xsl:for-each select="FlightDetails1">
<FlightDetails>
<CouponNumber>
<xsl:value-of select="CouponNumber" />
</CouponNumber>
<ServiceClass>
<xsl:value-of select="ServiceClass" />
</ServiceClass>
<CarrierCode>
<xsl:value-of select="CarrierCode" />
</CarrierCode>
</FlightDetails>
</xsl:for-each>
转换后生成的输出xml应如下所示:
<RestrictedTicket>abc</RestrictedTicket>
<FlightDetails>
<CouponNumber>1</CouponNumber>
<ServiceClass>F</ServiceClass>
<CarrierCode>SL</CarrierCode>
</FlightDetails>
<FlightDetails>
<CouponNumber>2</CouponNumber>
<ServiceClass>G</ServiceClass>
<CarrierCode>KL</CarrierCode>
</FlightDetails>
我不能在这里使用复制功能,因为我正在进行许多值之间的转换。我要做的是重复使用FlightDetails的代码,这样我就不需要写8次了(FlightDetails有8个重复标签,例如FlightDetails1,FlightDetails2 ...... FlightDetails8有类似的子标签)。目标是将持有标签从FlightDetails1更改为FlightDetails,并避免为8个flightdetails数据写入相同的代码8次。
答案 0 :(得分:2)
您正在寻找的表达式,它将选择 FlightDetail1 , FlightDetail2 (等等)元素:
<xsl:for-each select="*[starts-with(local-name(), 'FlightDetails')]">
但是,你提到重用代码,所以值得一提的是你应该使用XSLT Identity Transform来解决这个问题。
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
单独复制所有节点而不做任何更改。但是,这意味着您需要做的就是为要匹配的节点添加模板。因此,您不会使用 xsl:for-each ,而是使用模板匹配。
<xsl:template match="*[starts-with(local-name(), 'FlightDetails')]">
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(local-name(), 'FlightDetails')]">
<FlightDetails>
<xsl:apply-templates select="@*|node()"/>
</FlightDetails>
</xsl:template>
</xsl:stylesheet>
应用于以下XML
<Tickets>
<RestrictedTicket>abc</RestrictedTicket>
<FlightDetails1>
<CouponNumber>1</CouponNumber>
<ServiceClass>F</ServiceClass>
<CarrierCode>SL</CarrierCode>
</FlightDetails1>
<FlightDetails2>
<CouponNumber>2</CouponNumber>
<ServiceClass>G</ServiceClass>
<CarrierCode>KL</CarrierCode>
</FlightDetails2>
</Tickets>
以下是输出
<Tickets>
<RestrictedTicket>abc</RestrictedTicket>
<FlightDetails>
<CouponNumber>1</CouponNumber>
<ServiceClass>F</ServiceClass>
<CarrierCode>SL</CarrierCode>
</FlightDetails>
<FlightDetails>
<CouponNumber>2</CouponNumber>
<ServiceClass>G</ServiceClass>
<CarrierCode>KL</CarrierCode>
</FlightDetails>
</Tickets>
例如,了解如何编写用于复制 CouponNumber 或 ServiceClass 的任何显式代码。这是通过使用模板<xsl:template match="@*|node()">
实现的,因此重要的是此模板存在于XSLT中。
答案 1 :(得分:0)
感谢您的帮助。我修改了for-each,现在它完美无缺。修改后的xslt使用:
<xsl:for-each select="*[starts-with(local-name(), 'FlightDetails')]">
而不是<xsl:for-each select="FlightDetails1">.
其余代码保持不变。再次感谢您的帮助。