2015-12-05 44 views
0

我试图更新一些XSLT以适应新的XML输入格式。新的结构几乎打破了我以前的模板逻辑,但我试图避免重写整个过程。如何获取XSLT模板中参数的节点名称?

本质上,我想抓取模板参数的名称,删除前缀,并在<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="'&#xa;'" /> 

    <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> 

你会发现,并不是所有的值都是以上述两种格式提供。当依赖值不存在时,我需要重用父值。如果不存在,我需要使用“None”的值。输入格式已更改,以便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

请不要使用示例XML,上面写着'','',等当你的节点真的没有在其名称中的计数器。对于试图回答你的问题的人来说,编写XSLT是非常困难的。此外,修正示例中的语法错误,并使它们适合您的XSLT代码 - 或从您的XSLT代码中删除与您的问题无关的所有部分。 – Tomalak

+0

@Tomalak。固定。 – jktravis

+0

好的,还有一些'functx:stripCommas()'业务正在进行,这并没有什么实际影响,但它更好。对未来而言:将问题简化为本质有益于那些回答问题的人,对于下一个发现问题的人,而不是至少对你而言,因为它有助于充实自己的头脑。 – Tomalak

回答

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> 

有可能是一个更短的解决方案做同样的,但我想尽量减少所需的更改。

+0

我觉得那部分没关系。我想避免的是不得不离开我的'valueOrParentOrNone'模板,因为现在节点名称的前缀是'Dependent'(先前是'Another',但我更新了示例代码。)以前,逻辑是“if子节点存在,使用它,如果不存在,则使用父节点的相同节点名称的值,如果不存在,则使用无。“ – jktravis

1

只需使用

<xsl:sequence select="($fieldValue[.], replace($fieldValue, 'Dependent', ''),'None')[1]"/> 
+0

谢谢。不过,我不知道如何将这种情况应用于我的情况。你介意阐述吗? – jktravis

+0

@jktravis,通过对问题的描述,OP(你)肯定是需要阐述的人。这个问题,其编辑5,是完全混淆。在过去一个小时内阅读之后,我仍然不知道实际需要什么。你有没有看到Tomalak放弃并删除了他的答案? –

+0

我知道。我之前有更多的背景,但被要求将问题简化为核心。接受的解决方案适用于我的问题,并让我到我需要的地方。 – jktravis

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)]), 
     ','), 
     '&#xA;'"/> 
    <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)),','), 
     '&#xA;'"/> 
</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