2015-09-25 69 views
0

我需要修改和現有XML文檔以連接到字段值。我不知道如何做到這一點,因爲我無法將變量保留在範圍內。XSLT:連接兩個字段值如果不爲空

基本上,如果FirstName和LastName存在一個值,它應該輸出FirstName + LastName。如果FirstName或LastName中的一個或兩個值都爲空,則不應輸出FullName。請注意,這是一個現有的文檔,我無法修改第34行以上的任何現有代碼。

這是我到目前爲止有:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <xsl:template match="/"> 
    <AUTHENTICATOR> 
     <USERINFO> 
      <xsl:for-each select="/samlp:Response/*[local-name() = 'Assertion']/*[local-name() = 'AttributeStatement']/*"> 

       <xsl:if test="@Name='First_Name'"> 
        <xsl:variable name="firstname" select="*[local-name() = 'AttributeValue']" /> 
        <xsl:element name="field"> 
         <xsl:attribute name="name">FirstName</xsl:attribute>  
         <xsl:attribute name="value">  
          <xsl:for-each select="*[local-name() = 'AttributeValue']"> 
           <xsl:value-of select="normalize-space(current())"/> 
          </xsl:for-each> 
         </xsl:attribute> 
        </xsl:element> 
       </xsl:if> 

       <xsl:if test="@Name='Last_Name'"> 
        <xsl:variable name="lastname" select="*[local-name() = 'AttributeValue']" /> 
        <xsl:element name="field"> 
         <xsl:attribute name="name">LastName</xsl:attribute>  
         <xsl:attribute name="value">  
          <xsl:for-each select="*[local-name() = 'AttributeValue']"> 
           <xsl:value-of select="normalize-space(current())"/> 
          </xsl:for-each> 
         </xsl:attribute> 
        </xsl:element> 
       </xsl:if> 

       <!-- Unable to modify anything above this line--> 
       <!-- if firstname & lastname not null, concatinate firstname + lastname--> 
       <xsl:if test="not($firstname = '') or not($lastname = '')"> 
        <xsl:element name="field"> 
         <xsl:attribute name="name">FullName</xsl:attribute> 
         <xsl:attribute name="value"> 
          <xsl:value-of select="concat($firstname,'+',$lastname)" /> 
         </xsl:attribute> 
        </xsl:element> 
       </xsl:if> 

      </xsl:for-each> 

     </USERINFO> 
    </AUTHENTICATOR> 
    </xsl:template> 
</xsl:stylesheet> 

簡體XML以下文件:

<samlp:Response ID="_f9daea33-e32a-4dde-beb4-d5227690b1a3" Version="2.0" IssueInstant="2015-07-30T15:06:58.874Z" Destination="https://domain.net/Login/PAuthentication.aspx?configSet=SAML" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> 
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:jh:identityprovider</saml:Issuer> 
<samlp:Status> 
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /> 
</samlp:Status> 
<saml:Assertion Version="2.0" ID="_b54ca592-4401-4107-a426-281918091842" IssueInstant="2015-07-30T15:06:58.898Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> 
    <saml:AttributeStatement> 
     <saml:Attribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"> 
      <saml:AttributeValue>John</saml:AttributeValue> 
     </saml:Attribute> 
    </saml:AttributeStatement> 
      <saml:AttributeStatement> 
     <saml:Attribute Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"> 
      <saml:AttributeValue>Doe</saml:AttributeValue> 
     </saml:Attribute> 
    </saml:AttributeStatement> 
</saml:Assertion> 

+0

你能展示一個例子(最好是最小化)的輸入XML嗎? –

+0

參考 [如何檢查字符串在XSLT空或null] [1] [1]:http://stackoverflow.com/questions/825831/check-if-a-string-is -null-or-empty-in-xslt –

+0

從你的[上一個問題](http://stackoverflow.com/questions/32764372/xslt-assign-variable-value-from-xml),你學會了如何**不**使用'local-name()'。你應該真的用這個答案更新你的XSLT,因爲使用'local-name'很混亂並且容易出錯(正如Michael在答案中所表明的那樣)。 – Abel

回答

1

的例子是相當混亂 - 目前還不清楚什麼是 「記錄」以及您有多少條記錄(由您的XSLT判斷,只有一條記錄?)。

看看你是否可以用它作爲你的出發點。它假定每個saml:Assertion都是一條記錄,並且如果該記錄同時具有FirstName和LastName,則它會輸出一個FullName字段。

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
exclude-result-prefixes="samlp saml"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/samlp:Response"> 
    <AUTHENTICATOR> 
     <xsl:for-each select="saml:Assertion"> 
      <USERINFO> 
       <xsl:variable name="firstname" select="saml:AttributeStatement/saml:Attribute[@Name='FirstName']/saml:AttributeValue"/> 
       <xsl:variable name="lastname" select="saml:AttributeStatement/saml:Attribute[@Name='LastName']/saml:AttributeValue"/> 
       <xsl:if test="$firstname and $lastname"> 
        <field name="FullName" value="{concat($firstname, ' ', $lastname)}"/> 
       </xsl:if> 
      </USERINFO>   
     </xsl:for-each> 
    </AUTHENTICATOR>   
</xsl:template> 

</xsl:stylesheet> 

測試輸入

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> 
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> 
     <saml:AttributeStatement> 
     <saml:Attribute Name="FirstName"> 
      <saml:AttributeValue>John</saml:AttributeValue> 
     </saml:Attribute> 
     </saml:AttributeStatement> 
     <saml:AttributeStatement> 
     <saml:Attribute Name="LastName"> 
      <saml:AttributeValue>Doe</saml:AttributeValue> 
     </saml:Attribute> 
     </saml:AttributeStatement> 
    </saml:Assertion> 
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> 
     <saml:AttributeStatement> 
     <saml:Attribute Name="FirstName"> 
      <saml:AttributeValue>Madonna</saml:AttributeValue> 
     </saml:Attribute> 
     </saml:AttributeStatement> 
    </saml:Assertion> 
</samlp:Response> 

結果

<?xml version="1.0" encoding="UTF-8"?> 
<AUTHENTICATOR> 
    <USERINFO> 
    <field name="FullName" value="John Doe"/> 
    </USERINFO> 
    <USERINFO/> 
</AUTHENTICATOR> 

注意使用前綴到c的所有的元素都在源XML中。

+0

很高興看到你的方法也是去除那些令人困惑的'local-name()'調用。我在[對之前的同一個用戶的回答中提出了相同的數據](http://stackoverflow.com/questions/32764372/xslt-assign-variable-value-from-xml),以便比'saml'和' samlp「,因爲混合起來是導致錯誤結果的原因。 – Abel