我有以下模板,创建一个xml。一个模板中有多个类似的代码块。根据父元素名称,只有一个元素值。我对使用if test
而不仅仅是template match
的疑问也是一个不完美的想法?但那怎么样?:
<xsl:template match="Adresse">
<!-- TelefonG -> "Telefon Geschäftlich" (ID = 1) -->
<xsl:if test="TelefonG != '' or TelefonGZus != ''">
<xsl:if test="PersonGuid != ''">
<xsl:element name="AdrKontakt">
<KontaktGuid>
<xsl:value-of select="commonFunctions:createGuid()"/>
</KontaktGuid>
<PersonGuid>
<xsl:value-of select="commonFunctions:convertGuid(PersonGuid)"/>
</PersonGuid>
<InfoText>
<xsl:value-of select="commonFunctions:toHtmlEntities(TelefonG)"/>
</InfoText>
<Kommentar>
<xsl:value-of select="commonFunctions:toHtmlEntities(TelefonGZus)"/>
</Kommentar>
<xsl:element name="KontaktTypID">1</xsl:element>
<xsl:the-same-crap/>
</xsl:element>
</xsl:if>
</xsl:if>
<!-- TelefonP -> "Telefon Privat" (ID = 2) -->
<xsl:if test="TelefonP != '' or TelefonPZus != ''">
<xsl:if test="PersonGuid != ''">
<xsl:element name="AdrKontakt">
<xsl:the-same-crap/>
<xsl:element name="KontaktTypID">1</xsl:element>
<xsl:the-same-crap/>
</xsl:element>
</xsl:if>
</xsl:if>
<!-- TelMobil -> "Telefon Mobil" (ID = 3) -->
<xsl:if test="TelMobil != '' or TelMobilZus != ''">
<xsl:if test="PersonGuid != ''">
<xsl:element name="AdrKontakt">
<xsl:the-same-crap/>
<xsl:element name="KontaktTypID">3</xsl:element>
<xsl:the-same-crap/>
</xsl:element>
</xsl:if>
</xsl:if>
<xsl:and-so-on/>
输入xml如下所示:
...
<Adresse>
<PersonGuid>THEGUID01234567890</PersonGuid>
<TelefonP>0878938493</TelefonP>
<TelefonPZus>Some text about this number</TelefonPZus>
<TelefonG>9309340934</TelefonG>
<TelefonGZus>First class customer.</TelefnoGZus>
<TelefonM>090923409</TelefonM>
<TelefonMZus>Mobile because not always in office.</TelefonMZus>
<Email>abuse@bad.com</Email>
<EmailZus>suspect</EmailZus>
<!-- and so one -->
</Adresse>
<Adresse>
<Email>bla@foo.bar</Email>
<TelefonM>0298309283</TelefonM>
<Adresse>
...
你如何重构它来写同样的废话?有些开关盒吗?例如。 TelefonP =&gt; 1; TelMobil =&gt; 3等 提前致谢
答案 0 :(得分:1)
首先,除了当前的模板之外,我还要添加第二个模板,忽略没有 PersonGuid 的地址元素
<xsl:template match="Adresse[PersonGuid = '']" />
这是因为在所有三个模板中,您只输出有 PersonGuid 的新元素。这将简化模板中的代码,因为您可以在此条件下删除相应的 xsl:if 。
请注意,在这种情况下,XSLT将始终优先考虑更具体的模板。
至于重新分解代码,我认为你可以在这里使用 xsl:choose ,但是在你输出的 AdrKontakt 中定位。
<xsl:template match="Adresse">
<AdrKontakt>
<xsl:the-same-crap/>
<KontaktTypID>
<xsl:choose>
<xsl:when test="TelefonG != '' or TelefonGZus != ''">1</xsl:when>
<xsl:when test="TelefonP != '' or TelefonPZus != ''">1</xsl:when>
<xsl:when test="TelMobil != '' or TelMobilZus != ''">3</xsl:when>
<xsl:choose>
</KontaktTypID>
<xsl:the-same-crap/>
</AdrKontakt>
</xsl:tempalte>
<xsl:template match="Adresse[PersonGuid = '']" />
请注意,没有必要使用 xsl:element 在这里输出新元素,只需直接输出元素。
编辑:如果您需要输出多个 AdrKontakt ,那么您调用可能会使用带参数的命名模板来包含重复的代码:
命名模板如下所示:
<xsl:template name="AdrKontakt">
<xsl:param name="KontaktTypID" />
<AdrKontakt>
<xsl:the-same-crap/>
<KontaktTypID>
<xsl:value-of select="$KontaktTypID" />
</KontaktTypID>
<xsl:the-same-crap/>
</AdrKontakt>
</xsl:tempalte>
打电话给你,你会这样做:
<xsl:template match="Adresse">
<xsl:if test="TelefonG != '' or TelefonGZus != ''">
<xsl:call-template name="AdrKontakt">
<xsl:with-param name="KontaktTypID" select="'1'" />
</xsl:call-template>
</xsl:if>
<xsl:if test="TelefonP != '' or TelefonPZus != ''">
...
等等你的其他条件。您将无法消除 xsl:lf ,但您重复的代码现在只会出现在一个地方。
请注意,在指定模板 AdrKontakt 中,您当前的上下文仍然是 Adresse 元素,因此您仍然可以输出当前的其他元素:
<xsl:template name="AdrKontakt">
<xsl:param name="KontaktTypID" />
<AdrKontakt>
<InfoText>
<xsl:value-of select="commonFunctions:toHtmlEntities(TelefonG)"/>
</InfoText>
<KontaktTypID>
<xsl:value-of select="$KontaktTypID" />
</KontaktTypID>
</AdrKontakt>
</xsl:tempalte>