我试图更新一些XSLT以容纳新的XML输入格式。新结构几乎打破了我以前的模板逻辑,但我试图避免重写整个过程。
基本上,我想获取模板参数的名称,删除前缀,并在<xsl:value-of/>
中使用结果。例如:
<!-- calling location -->
<xsl:call-template name="myTemplate">
<xsl:with-param name="field" select="Name"/>
</xsl:call-template>
<!-- template to do the processing. -->
<xsl:template name="myTemplate">
<xsl:param name="field"/>
<xsl:variable name="fieldName" select="replace($field, 'Prefix', '')"/>
<xsl:value-of select="$fieldName"/>
</xsl:template>
背景。
自从我被要求提供问题的本质和整个背景以来,这更像是一个问题。我的样式表的简化版本如下所示:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:variable name="delimiter" select="','" />
<xsl:variable name="newline" select="'
'" />
<xsl:template match="/root">
<xsl:apply-templates select="entry"/>
<xsl:apply-templates select="entry/Dependents"/>
</xsl:template>
<xsl:template match="entry">
<xsl:value-of select="Name"/>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="Address"/>
<xsl:value-of select="$delimeter"/>
<xsl:value-of select="Phone"/>
<xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="entry/Dependents">
<xsl:call-template name="valueOrParentOrNone">
<xsl:with-param name="fieldValue" select="Name"/>
</xsl:call-template>
<xsl:value-of select="$delimeter"/>
<xsl:call-template name="valueOrParentOrNone">
<xsl:with-param name="fieldValue" select="Address"/>
</xsl:call-template>
<xsl:value-of select="$delimeter"/>
<xsl:call-template name="valueOrParentOrNone">
<xsl:with-param name="fieldValue" select="Phone"/>
</xsl:call-template>
<xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template name="valueOrParentOrNone">
<xsl:param name="fieldValue"/>
<xsl:choose>
<!-- Use passed in node if exists -->
<xsl:when test="$fieldValue">
<xsl:value-of select="$fieldValue" />
</xsl:when>
<!-- Use parent node of the same name if exists -->
<xsl:when test="../$fieldName">
<xsl:value-of select="../$fieldName" />
</xsl:when>
<!-- Use "None" -->
<xsl:otherwise>
<xsl:text>"None"</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
原始输入XML:
<root>
<entry>
<Name>J. Smith</Name>
<Address>1123 XML Lane</Address>
<Phone>123-456-7890</Phone>
<Dependents>
<Name>S. Smith</Name>
<Address>1123 XML Lane</Address>
<Phone>123-456-0987</Phone>
</Dependents>
</entry>
<entry>
<Name>L. Hines</Name>
<Address>423 Programming Way</Address>
<Dependents>
<Name>P. Hines</Name>
</Dependents>
</entry>
</root>
新输入XML
<root>
<entry>
<Name>J. Smith</Name>
<Address>1123 XML Lane</Address>
<Phone>123-456-7890</Phone>
<DependentName>S. Smith</DependentName>
<DependentAddress>1123 XML Lane</DependentAddress>
<DependentPhone>123-456-0987</DependentPhone>
</entry>
<entry>
<Name>L. Hines</Name>
<Address>423 Programming Way</Address>
<DependentName>P. Hines</DependentName>
</entry>
</root>
您会注意到并非所有值都以上述任何一种格式提供。当依赖值不存在时,我需要重用父值。如果两者都不存在,我需要使用&#34; None&#34;的值。输入格式已更改,以便Dependents
兄弟不再存在。相反,Dependents
的孩子已经成长为普通人价值观的兄弟姐妹,现在是entry
的直接孩子。
预期输出。
"J. Smith","1123 XML Lane","123-456-7890"
"S. Smith","1123 XML Lane","123-456-0987"
"L. Hines","423 Programming Way",,
"P. Hines","423 Programming Way","None"
编辑:很抱歉让人困惑。
答案 0 :(得分:1)
恕我直言,您最好的选择是将模板重写为:
<xsl:template name="valueOrAltOrNone">
<xsl:param name="field"/>
<xsl:param name="alt-field"/>
<xsl:choose>
<xsl:when test="$field">
<xsl:value-of select="$field" />
</xsl:when>
<xsl:when test="$alt-field">
<xsl:value-of select="$alt-field" />
</xsl:when>
<xsl:otherwise>
<xsl:text>"None"</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
并将其称为(例如):
<xsl:call-template name="valueOrAltOrNone">
<xsl:with-param name="field" select="DependentName"/>
<xsl:with-param name="alt-field" select="Name"/>
</xsl:call-template>
可能有一个较短的解决方案,但我想尽量减少所需的更改。
答案 1 :(得分:1)
只需使用:
<xsl:sequence select="($fieldValue[.], replace($fieldValue, 'Dependent', ''),'None')[1]"/>
答案 2 :(得分:1)
这是一个完整的转型:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="my:f">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="entry">
<xsl:value-of select="string-join(
(string(Name), string(Address), string(Phone), ''[not(current()/Phone)]),
','),
'
'"/>
<xsl:apply-templates select="." mode="dependent"/>
</xsl:template>
<xsl:template match="entry" mode="dependent">
<xsl:value-of select="string-join(
(f:getValue(.,Name, DependentName), f:getValue(.,Address, DependentAddress),
f:getValue(.,Phone, DependentPhone)),','),
'
'"/>
</xsl:template>
<xsl:function name="f:getValue">
<xsl:param name="pParent" as="element()"/>
<xsl:param name="pChild" as="xs:string?"/>
<xsl:param name="pdepChild" as="xs:string?"/>
<xsl:variable name="vUsethis" select="($pdepChild, $pChild)[1]"/>
<xsl:sequence select="($vUsethis[.],'None')[1]"/>
</xsl:function>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<root>
<entry>
<Name>J. Smith</Name>
<Address>1123 XML Lane</Address>
<Phone>123-456-7890</Phone>
<DependentName>S. Smith</DependentName>
<DependentAddress>1123 XML Lane</DependentAddress>
<DependentPhone>123-456-0987</DependentPhone>
</entry>
<entry>
<Name>L. Hines</Name>
<Address>423 Programming Way</Address>
<DependentName>P. Hines</DependentName>
</entry>
</root>
产生了想要的正确结果:
J. Smith,1123 XML Lane,123-456-7890
S. Smith,1123 XML Lane,123-456-0987
L. Hines,423 Programming Way,,
P. Hines,423 Programming Way,None