我对XSLT比较陌生,而且我遇到了从给定的xml中选择属性和节点值的逻辑。
这是我的xml,
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:head="http://www/example.com">
<soap:Header>
<head:sampleHeaderType>
<head:messageId>xxxxxxxx</head:messageId>
<head:SID>XXX</head:SID>
<head:BID>SP</head:BID>
<head:CTS>2014-09-26T13:19:30.534Z</head:CTS>
</head:sampleHeaderType>
</soap:Header>
<soap:Body>
<cass:SPD xmlns:cass="http://blahblahblah">
<cass:SPR>
<cass:RQ RT="Describe" FG="LOL" PD="09/22/2014" />
</cass:SPR>
<cass:SPS>
<cass:SP SPT="Standard" FT="Retail" PS="New" ICT="APR" >
<cass:DR DN="306532" BR="0.0790000">
<cass:FFMR ValueType="$" Value="0"/>
<cass:RV ReserveType="DP">
<cass:RTS TT="DP">
<cass:RT TMin="0" TMax="0.999999" TVT="%" TV="100"/>
</cass:RTS>
</cass:RV>
</cass:DR>
<cass:Product PID="Sirius" PN="Sirius"/>
</cass:SP>
<cass:SP SPT="Standard" FT="Retail" PS="New" ICT="APR">
<cass:DR DN="306532" BR="0.1520000">
<cass:FFMR ValueType="$" Value="0"/>
<cass:RV RT="DP">
<cass:RTS TT="DP">
<cass:RT TMin="0" TMax="0.999999" TVT="%" TV="100"/>
</cass:RTS>
</cass:RV>
</cass:DR>
<cass:Product PID="Sirius" PN="Sirius"/>
</cass:SP>
</cass:SPS>
<cass:SPMS>
<cass:SPM MessageCode="" MessageType="" MessageText=""/>
</cass:SPMS>
</cass:SPD>
</soap:Body>
</soap:Envelope>
这是我期待的输出:
<CALL_ENGINE_RESPONSE>
<EVAPP_SP>
<RT>Describe</RT>
<FG>LOL</FG>
<ICT>APR</ACT>
<DN>306532</DN>
<TMIN>0</TMIN>
<MessageCode></MessageCode>
<MessageText></MessageText>
</EVAPP_SP>
<EVAPP_SP>
<RT>Describe</RT>
<FG>LOL</FG>
<ICT>APR</ACT>
<DN>306532</DN>
<TMIN>0</TMIN>
<MessageCode></MessageCode>
<MessageText></MessageText>
</EVAPP_SP>
</CALL_ENGINE_RESPONSE>
基本上,xml中可以存在多个SPS段,对于每个SPS,我们希望使用EVAPP_SP标记构建单独的XML。但是RQ和SPM只出现一次。
我的样式表可能看起来很可怕,因为我的无知,但这里是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:cass="http://blahblahblah" xmlns:head="http://www/example.com" exclude-result-prefixes="soap cass head">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="cass:SPD">
<CALL_ENGINE_RESPONSE>
<xsl:apply-templates select="cass:SPM"/>
<xsl:apply-templates select="cass:RQ"/>
<xsl:apply-templates select="cass:SP"/>
</CALL_ENGINE_RESPONSE>
</xsl:template>
<xsl:template match="cass:RQ">
<EVAPP_SP>
<RT>
<xsl:value-of select="@RT"/>
</RT>
<FG>
<xsl:value-of select="@FG"/>
</FG>
<PD>
<xsl:value-of select="@PD"/>
</PD>
</EVAPP_SP>
</xsl:template>
<xsl:template match="cass:SPM">
<EVAPP_SP>
<MESSAGE_TXT>
<xsl:value-of select="@MessageText"/>
</MESSAGE_TXT>
</EVAPP_SP>
</xsl:template>
</xsl:stylesheet>
到目前为止,我得到了输出:
xxxxxxxx
XXX
SP
2014-09-26T13:19:30.534Z
<CALL_ENGINE_RESPONSE/>
它正在拾取标题信息,我想完全忽略的命名空间和标记。
有人可以建议我必须前往的好方向吗?例如,如何使样式表忽略标题?
答案 0 :(得分:1)
您在标题中看到的行为是由XSLT built-in template rules引起的。这些是在XSLT寻找模板匹配时使用的模板,但在XSLT中没有匹配的模板。
你有一个模板匹配&#34; cass:SPD&#34;。然而,元素&#34;肥皂:标题&#34;和&#34;肥皂:身体&#34;在此之前,所以默认模板将用于这些。最终,内置模板将输出文本节点,这就是您看到标题文本出现的原因。
要停止此操作,只需将此模板匹配添加到您的XSLT
即可<xsl:template match="soap:Header" />
我能看到的另一个问题是你的模板匹配&#34; cass:SPD&#34;你这样做
<xsl:apply-templates select="cass:SPM"/>
<xsl:apply-templates select="cass:RQ"/>
<xsl:apply-templates select="cass:SP"/>
但是这些元素中没有一个看起来是&#34; cass:SPD&#34;的子节点,所以你可能需要这样做:
<xsl:apply-templates select="*/cass:SPM"/>
<xsl:apply-templates select="*/cass:RQ"/>
<xsl:apply-templates select="*/cass:SP"/>
或者也许是这样,如果你不知道它们发生了多远
<xsl:apply-templates select=".//cass:SPM"/>
<xsl:apply-templates select=".//cass:RQ"/>
<xsl:apply-templates select=".//cass:SP"/>