2013-02-22 88 views
2

這似乎很簡單,但我似乎無法讓它工作。XSLT迭代子節點

我的XML看起來是這樣的:

<bsar:BSAForm> 
    <bsar:SubjectInformation> 
     <bsar:LastNameOrNameOfEntity> Obama</bsar:LastNameOrNameOfEntity> 
     <bsar:AddressBlock> 
      <ucc:Address> 9 Dale Rd</ucc:Address> 
      <ucc:City> Woodbury</ucc:City> 
     </bsar:AddressBlock> 
     <bsar:AddressBlock> 
      <ucc:Address> 123 Fake St</ucc:Address> 
      <ucc:City> Springfield</ucc:City> 
     </bsar:AddressBlock> 
    </bsar:SubjectInformation> 
</bsar:BSAForm> 

我需要遍歷這兩個元素和顯示內容。我的XSLT是這樣的:

<xsl:template match=/bsar:BSAForm"> 
    <xsl:apply-templates select="bsar:SubjectInformation"/> 
</xsl:template> 

<xsl:template match="bsar:SubjectInformation"> 
    <xsl:text xml:space="preserve">4A</xsl:text> 
    <xsl:text xml:space="preserve">00001</xsl:text> 
    <xsl:value-of select="bsar:LastNameOrNameOfEntity"/> 
    <xsl:value-of select="'&#xD;&#xA;'"/> <!-- new line --> 

    <xsl:apply-templates select="bsar:AddressBlock"/> 
</xsl:template> 

<xsl:template match="bsar:AddressBlock"> 

    <xsl:variable name="Addr" select="../bsar:AddressBlock"/> 

    <xsl:text xml:space="preserve">4B</xsl:text> 
    <xsl:text xml:space="preserve">00001</xsl:text> 
    <xsl:value-of select="$Addr/ucc:Address"/> 
    <xsl:value-of select="$Addr/ucc:City"/> 
    <xsl:value-of select="'&#xD;&#xA;'"/> <!-- new line --> 
</xsl:template> 

輸出應該如下:

4A 00001 Obama 
4B 9 Dale Rd Woodbury 
4B 123 Fake St Springfield 

而是輸出出來是這樣的:

4A 00001 Obama 
4B 9 Dale Rd Woodbury 
4B 9 Dale Rd Woodbury 

我已經嘗試了許多不同的方法來做到這一點,每個使用一個,使用每個像這樣:

<xsl:variable name="header" select="."/> 
<xsl:for-each select="following-sibling::bsar:TelephoneBlock[ancestor::bsar:SubjectInformation[1] = $header]"> 

或者甚至傳遞一個計數器從一個for循環和使用,以訪問指定的元件是這樣的:

<xsl:for-each select="bsar:TelephoneBlock"> 
    <xsl:variable name="Index"> 
     <xsl:number count="bsar:TelephoneBlock" /> 
    </xsl:variable> 

    <xsl:call-template name="SubjectPhone"> 
     <xsl:with-param name="$Index"/> 
    </xsl:call-template> 
</xsl:for-each> 

<xsl:template name="SubjectPhone"> 
    <xsl:param name="Index"/> 

    <xsl:variable name="Telephone" select="../bsar:TelephoneBlock[$Index]"/> 
    ... 
</xsl:template> 

在所有這些情況下,它是兩次顯示所述第一地址。請讓我知道你是否注意到我做錯了什麼。

在此先感謝。

回答

3
<xsl:variable name="Addr" select="../bsar:AddressBlock"/> 

bsar:AddressBlock模板內將Addr變量設置爲包含所有當前元素的父下bsar:AddressBlock元件節點集,即當前AddressBlock及其所有兄弟AddressBlock元素。當您以後來到

<xsl:value-of select="$Addr/ucc:Address"/> 

這將選擇包含所有$Addr所有AddressBlock元素的ucc:Address子元素的節點集,然後在文檔順序第一這樣的元素轉換爲它的字符串值(定義在XPath 1.0中設置的節點的「字符串值」是其第一個節點的字符串值)。這將始終是第一個AddressBlock中的ucc:Address,這就是您看到相同地址兩次的原因。

但變量是聯合國必要的,因爲你適用於一個AddressBlock一次一個模板是 - 只是說

<xsl:template match="bsar:AddressBlock"> 
    <xsl:text>4B</xsl:text> 
    <xsl:text>00001</xsl:text> 
    <xsl:value-of select="ucc:Address"/> 
    <xsl:value-of select="ucc:City"/> 
    <xsl:value-of select="'&#xD;&#xA;'"/> <!-- new line --> 
</xsl:template> 

select表現將是相對於當前AddressBlock,並提取其地址和城市具體,併產生

4A00001 Obama 
4B00001 9 Dale Rd Woodbury 
4B00001 123 Fake St Springfield 

這並不依賴於一個事實,即有在原始XML每個地址和城市價值的開始領先的空間,你可能更願意這樣說

<xsl:template match="bsar:AddressBlock"> 
    <xsl:text>4B </xsl:text> 
    <xsl:text>00001 </xsl:text> 
    <xsl:value-of select="normalize-space(ucc:Address)"/> 
    <xsl:text> </xsl:text> 
    <xsl:value-of select="normalize-space(ucc:City)"/> 
    <xsl:value-of select="'&#xD;&#xA;'"/> <!-- new line --> 
</xsl:template> 

(注意xml:space="preserve"<xsl:text>默認的,所以你並不需要顯式地指定它)

+0

你說得對。願你活到一千歲。 – 2013-02-22 15:48:54