簡體   English   中英

XSLT從XML分配變量值

[英]XSLT assign variable value from XML

從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>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <Reference URI="#_f9daea33-e32a-4dde-beb4-d5227690b1a3">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <InclusiveNamespaces PrefixList="#default samlp saml ds xs xsi"
                            xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
                    </Transform>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                <DigestValue>uL1LoegsT53UGJE/HQqG9VW1Mnc=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>ifdW4P9/</SignatureValue>
        <KeyInfo>
            <X509Data>
                <X509Certificate>MIIHwzCCBaugAwIBAgIKeH+</X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
    <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:Issuer>urn:jh:identityprovider</saml:Issuer>
        <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
                >ZQA|brandtest</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml:SubjectConfirmationData NotOnOrAfter="2015-07-30T16:06:59.331Z"
                    Recipient="https://jacksonhewitt.brandmuscle.net/Login/PAuthentication.aspx?configSet=SAML"
                 />
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2015-07-30T14:06:59.331Z"
            NotOnOrAfter="2015-07-30T16:06:59.331Z">
            <saml:AudienceRestriction>
                <saml:Audience>https://domain.net/Login/PAuthentication.aspx?configSet=SAML</saml:Audience>
                <saml:Audience>https://domain.net/</saml:Audience>
            </saml:AudienceRestriction>
        </saml:Conditions>
        <saml:AttributeStatement>
            <saml:Attribute Name="Phone"
                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
                <saml:AttributeValue>867-5309</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
        <saml:AttributeStatement>
            <saml:Attribute Name="Phone2"
                NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
                <saml:AttributeValue>555-1212</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
        <saml:AuthnStatement AuthnInstant="2015-07-30T15:06:59.335Z">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
    </saml:Assertion>
</samlp:Response>

XSLT文件:

<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']/*">

            <!--This one works -->  
            <xsl:if test="(@Name='Phone')">
                <xsl:variable name="phone" select="*[local-name() = 'AttributeValue']" />
                <xsl:value-of select="$phone"/>
            </xsl:if>

            <!--This one doesn't work -->
            <xsl:variable name="phone2" select="samlp:AttributeValue[../@Name = 'Phone2']" />
            <xsl:value-of select="$phone2"/>

            </xsl:for-each>

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

嘗試輸出變量的值時,它為空。 我猜我在xsl:variable中的“選擇”語法不正確?

我可以使它像使用下面的代碼一樣工作,但是我不想使用'if'。

    <xsl:if test="(@Name='Phone')">
       <xsl:variable name="phone" select="*[local-name() = 'AttributeValue']" />
       <xsl:value-of select="$phone"/>
    </xsl:if>

這里的關鍵問題是重點是什么。 盡管proycon回答表明您已經使用屬性軸(帶有@ )來訪問元素節點,並且忘記了使用名稱空間前綴,但是如果沒有獲取值,則焦點可能不會放在saml:Attribute 如果不看其余的代碼,很難分辨出哪里出錯了。

假設您有:

<xsl:template match="Attribute">
   <!-- your variable here -->

那么模板將永遠不會被匹配,因為它不在正確的名稱空間中。 但是,即使將其設置為match="saml:Attribute" ,變量也會以*開頭,它是child::*縮寫,並且在saml:Attribute下沒有具有Name saml:Attribute

假設您有:

<xsl:template match="saml:Xyz">
   <!-- your variable here -->

那么您的重點是其他一些節點Xyz

要解決此問題,您需要周圍的焦點設置表達式( xsl:templatexsl:for-each )來選擇saml:Attribute的父對象,或者如果焦點是其他對象,則需要解決表達式本身。 根據樣式表的其余部分(即,是否將模板應用於此節點,此處顯示為淺跳過模式),​​以下操作將起作用:

僅輸出電話號碼:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="node() | @*">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="saml:Attribute[@Name = 'Phone']">
        <xsl:variable name="phone" select="saml:AttributeValue" />
        <xsl:value-of select="$phone" />
    </xsl:template>

</xsl:stylesheet>

更新(Q.更新之后)

當我輸入答案時,您說過您不想使用xsl:if ,並且可以將其與以下代碼一起使用:

<xsl:if test="(@Name='Phone')">
   <xsl:variable name="phone" select="*[local-name() = 'AttributeValue']" />
   <xsl:value-of select="$phone"/>
</xsl:if>

一些興趣點:

  1. 除非沒有解決辦法,否則如果直接使用NameTest即可,請不要使用local-name() ,在這種情況下,請使用saml:AttributeValue (不要忘記將名稱空間添加到xsl:stylesheet根元素中)
  2. xsl:if/@test中的括號是多余的
  3. 沒錯,您不需要xsl:if 您可以簡單地將變量更改為指向saml:AttributeValue[../@Name='Phone'] ,它將選擇無,除非其父項在Name屬性中具有Phone 0.換句話說,這是相同的:

     <xsl:variable name="phone" select="saml:AttributeValue[../@Name = 'Phone']" /> 

盡管AttributeValue名稱具有誤導性,但它是一個元素,而不是屬性;)因此,請使用*[@Name='Phone']/saml:AttributeValue

如果出於任何原因您不想使用前綴,也不想使用if ,則可以使用以下命令:

        <xsl:variable name="phone" select="*[@Name='Phone']/*[local-name() = 'AttributeValue']" />
        <xsl:value-of select="$phone"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM