2015-12-05 43 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