我想选择属性的下一个兄弟来输出句点。 此模板正在选择所需的属性。
唯一有效的解决方案是我匹配属性的名称并选择我需要的那个。如何使用少量线使其更通用? 我已经尝试过跟随兄弟姐妹'但这只适用于元素。
功能代码;
...
<Period >
<xsl:attribute name="Unit">
<xsl:choose>
<xsl:when test="local-name()='BonusAmount'">
<xsl:value-of select="../@BonusFrequency"/>
</xsl:when>
<xsl:when test="local-name()='CommissionAmount'">
<xsl:value-of select="../@CommissionFrequency"/>
</xsl:when>
<xsl:when test="local-name()='GrossRegularOvertimeAmount'">
<xsl:value-of select="../@GrossRegularOvertimeFrequency"/>
</xsl:when>
<xsl:when test="local-name()='GrossSalaryAmount'">
<xsl:value-of select="../@GrossSalaryFrequency"/>
</xsl:when>
<xsl:when test="local-name()='CarAllowanceAmount'">
<xsl:value-of select="../@CarAllowanceFrequency"/>
</xsl:when>
<xsl:when test="local-name()='WorkAllowanceAmount'">
<xsl:value-of select="../@WorkAllowanceFrequency"/>
</xsl:when>
<xsl:when test="local-name()='WorkersCompensationAmount'">
<xsl:value-of select="../@WorkersCompensationFrequency"/>
</xsl:when>
</xsl:choose>
</xsl:attribute>
</Period>
...
XML示例:
<Employment>
<PAYG Basis="Temporary" Industry="Oil and Gas Extraction" IndustryCode="0700" Occupation="General Waiter" OccupationCode="6323-11" OnProbation="Yes" ProbationDateEnds="2019-03-27" StartDate="2014-05-05" Status="Secondary" UniqueID="c8492d8c-34fc-419b-93f4-f1f3" x_Employer="c46c9077-31ef-4daa-b8cc-c9e3">
<Income BonusAmount="89898985" BonusFrequency="Monthly" CommissionAmount="4488" CommissionFrequency="Yearly" GrossRegularOvertimeAmount="365" GrossRegularOvertimeFrequency="Fortnightly" GrossSalaryAmount="4798" GrossSalaryFrequency="Weekly" WorkAllowanceAmount="10101010" WorkAllowanceFrequency="Monthly"/>
</PAYG>
</Employment>
输出:
<ValueItem Value="89898985">
<Identifier UniqueID="c8492d8c-34fc-419b-93f4-f1f3-Income-PAYG-BonusAmount"/>
<PercentOwned Percent="100">
<RelatedEntityRef RelatedID="baaef85e-3793-4fe8-8c62-8cc766fa490b"/>
</PercentOwned>
<Income Type="Bonus">
<Period Unit="Monthly"/>
<RelatedEntityRef RelatedID="c46c9077-31ef-4daa-b8cc-c9e3"/>
</Income>
</ValueItem>
<ValueItem Value="4488">
<Identifier UniqueID="c8492d8c-34fc-419b-93f4-f1f3-Income-PAYG-CommissionAmount"/>
<PercentOwned Percent="100">
<RelatedEntityRef RelatedID="baaef85e-3793-4fe8-8c62-8cc766fa490b"/>
</PercentOwned>
<Income Type="Commission">
<Period Unit="Yearly"/>
<RelatedEntityRef RelatedID="c46c9077-31ef-4daa-b8cc-c9e3"/>
</Income>
</ValueItem>
<ValueItem Value="365">
<Identifier UniqueID="c8492d8c-34fc-419b-93f4-f1f3-Income-PAYG-GrossRegularOvertimeAmount"/>
<PercentOwned Percent="100">
<RelatedEntityRef RelatedID="baaef85e-3793-4fe8-8c62-8cc766fa490b"/>
</PercentOwned>
<Income Type="GrossRegularOvertime">
<Period Unit="Fortnightly"/>
<RelatedEntityRef RelatedID="c46c9077-31ef-4daa-b8cc-c9e3"/>
</Income>
</ValueItem>
<ValueItem Value="4798">
<Identifier UniqueID="c8492d8c-34fc-419b-93f4-f1f3-Income-PAYG-GrossSalaryAmount"/>
<PercentOwned Percent="100">
<RelatedEntityRef RelatedID="baaef85e-3793-4fe8-8c62-8cc766fa490b"/>
</PercentOwned>
<Income Type="GrossSalary">
<Period Unit="Weekly"/>
<RelatedEntityRef RelatedID="c46c9077-31ef-4daa-b8cc-c9e3"/>
</Income>
</ValueItem>
等
答案 0 :(得分:0)
对于XSLT 2.0及更高版本,您可以使用fn:replace()
XPath function,如下所示:
<Period Unit="{../@*[name()= replace(name(current()),'Amount','Frequency')]}"/>
XSLT 1.0没有此功能。其中一种解决方法如下(将任意输入字符串映射到任意输出字符串,这比replace()
可以做的更灵活一些):
<xsl:transform
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://tempuri.org/"
exclude-result-prefixes="my"
>
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<my:config>
<map value="BonusAmount">BonusFrequency</map>
<map value="CommissionAmount">CommissionFrequency</map>
<!-- ... -->
</my:config>
<xsl:variable name="config" select="document('')/*/my:config" />
<xsl:template match="@*" mode="create-period">
<xsl:variable name="mapping" select="$config/map[@value = name(current())]" />
<xsl:if test="$mapping">
<Period Unit="{../@*[name() = $mapping]}" />
</xsl:if>
</xsl:template>
</xsl:transform>
注意:
document('')
可用于访问当前的XSLT文档exclude-result-prefixes
可防止名称空间泄漏到输出文档中<xsl:attribute>
(只要属性名称是固定的,就像你的情况一样)。@*
匹配的其他模板。需要在应用模板时设置。另一种可能性包括string-replace
template或使用EXSLT replace
extension function - 许多XSLT 1.0处理器都支持EXSLT。
答案 1 :(得分:0)
我不确定我是否完全理解这一点 如果您需要查找以 Amoun 结尾的每个属性,以频率结尾的属性 你可以试试这样的黑客:
<xsl:template match="PAYG">
<test>
<xsl:apply-templates select="Income/@*" />
</test>
</xsl:template>
<xsl:template match="Income/@*">
<xsl:variable name="a" select="local-name()" />
<xsl:if test="'Amount' = substring( $a, string-length($a) - string-length('Amount') + 1 )">
<xsl:variable name="f" select="concat( substring-before( $a, 'Amount' ), 'Frequency' )"/>
<Period >
<xsl:attribute name="Unit">
<xsl:value-of select="../@*[local-name() = $f]"/>
</xsl:attribute>
<xsl:value-of select="local-name()"/>
</Period>
</xsl:if>
</xsl:template>
将输出:
<test>
<Period Unit="Monthly">BonusAmount</Period>
<Period Unit="Yearly">CommissionAmount</Period>
<Period Unit="Fortnightly">GrossRegularOvertimeAmount</Period>
<Period Unit="Weekly">GrossSalaryAmount</Period>
<Period Unit="Monthly">WorkAllowanceAmount</Period>
</test>