2010-12-07 56 views
1

我需要將<amendment/>元素拉到<sectionid/>,<amendmenttext/><sponsor/>元素(如果可用)。使用XSLT得到最後一組兄弟前代

下面是一個例子:

來自:

<root> 
     <amendment> 
      <id>1</id> 
      <text>some text</text> 
     </amendment> 
     <sectionid>A</sectionid> 
     <sponsor>jon</sponsor> 
     <sponsor>peter</sponsor> 
     <amendment> 
      <id>8</id> 
      <text>some text</text> 
     </amendment> 
     <sectionid>B</sectionid> 
     <sponsor>matt</sponsor> 
     <sponsor>ben</sponsor> 
     <amendmenttext>some intro text</amendmenttext> 
     <amendment> 
      <id>5</id> 
      <text>some text</text> 
     </amendment> 
     <amendment> 
      <id>4</id> 
      <text>some text</text> 
     </amendment> 
     <sponsor>max</sponsor> 
     <amendment> 
      <id>6</id> 
      <text>some text</text> 
     </amendment> 
     <amendment> 
      <id>7</id> 
      <text>some text</text> 
     </amendment> 

</root> 

到:

<root> 
     <amendment>     
      <id>1</id> 
      <text>some text</text> 
     </amendment>   
     <amendment> 
      <sectionid>A</sectionid> 
      <sponsor>jon</sponsor> 
      <sponsor>peter</sponsor> 
      <id>8</id> 
      <text>some text</text> 
     </amendment> 
     <amendment> 
      <sectionid>B</sectionid> 
      <sponsor>matt</sponsor> 
      <sponsor>ben</sponsor> 
      <amendmenttext>some intro</amendmenttext> 
      <id>5</id> 
      <text>some text</text> 
     </amendment> 
     <amendment> 
      <sectionid>B</sectionid> 
      <sponsor>matt</sponsor> 
      <sponsor>ben</sponsor> 
      <id>4</id> 
      <text>some text</text> 
     </amendment> 
     <amendment> 
      <sectionid>B</sectionid> 
      <sponsor>max</sponsor> 
      <id>6</id> 
      <text>some text</text> 
     </amendment> 
     <amendment> 
      <sectionid>B</sectionid> 
      <sponsor>max</sponsor> 
      <id>7</id> 
      <text>some text</text> 
     </amendment> 

</root> 

注1:<sectionid/>元件適用於所有<amendments/>下一<sectionid/>

之前注2:<sponsor/>元素適用於所有<amendments/>之前的下一個<sponsor/>列表。

注3://amendment/id的值不是連續的。

注4:<amendment/>不能有<sponsor/><sectionid/>作爲前兄弟。

注5:<amendmenttext>僅適用於以下<amendment/>

這怎麼轉型與XSLT 1.0完成。

+0

上一個問題的修改http://stackoverflow.com/questions/4096481/refactor-xml-with-xsl是次要的。我認爲這不值得一個新的問題。 – 2010-12-07 16:25:07

+0

Oki。不知道解決方案是相似的。我認爲原來的迴應者在回答問題後改變問題的背景是不公平的。但有一點要說。 – 2010-12-07 17:07:22

回答

2

這個樣式表(相同的答案比以前只是一個規則):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="node()|@*"> 
     <xsl:param name="pSectionId" select="/.."/> 
     <xsl:param name="pSponsors" select="/.."/> 
     <xsl:variable name="vSectionid" select="self::sectionid"/> 
     <xsl:variable name="vSponsor" select="self::sponsor"/> 
     <xsl:variable name="vAmendment" select="self::amendment"/> 
     <xsl:if test="not($vSectionid|$vSponsor)"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*"/> 
       <xsl:copy-of select="$pSectionId[$vAmendment]"/> 
       <xsl:copy-of select="$pSponsors[$vAmendment]"/> 
       <xsl:apply-templates select="node()[1]"/> 
      </xsl:copy> 
     </xsl:if> 
     <xsl:apply-templates select="following-sibling::node()[1]"> 
      <xsl:with-param name="pSectionId" 
          select="$pSectionId[not($vSectionid)]|$vSectionid"/> 
      <xsl:with-param name="pSponsors" 
          select="$pSponsors[not($vSponsor) or 
               current() 
                /preceding-sibling::node()[1] 
                /self::sponsor] | 
            $vSponsor"/> 
     </xsl:apply-templates> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<root> 
    <amendment> 
     <id>1</id> 
     <text>some text</text> 
    </amendment> 
    <amendment> 
     <sectionid>A</sectionid> 
     <sponsor>jon</sponsor> 
     <sponsor>peter</sponsor> 
     <id>8</id> 
     <text>some text</text> 
    </amendment> 
    <amendment> 
     <sectionid>B</sectionid> 
     <sponsor>matt</sponsor> 
     <sponsor>ben</sponsor> 
     <id>5</id> 
     <text>some text</text> 
    </amendment> 
    <amendment> 
     <sectionid>B</sectionid> 
     <sponsor>matt</sponsor> 
     <sponsor>ben</sponsor> 
     <id>4</id> 
     <text>some text</text> 
    </amendment> 
    <amendment> 
     <sectionid>B</sectionid> 
     <sponsor>max</sponsor> 
     <id>6</id> 
     <text>some text</text> 
    </amendment> 
    <amendment> 
     <sectionid>B</sectionid> 
     <sponsor>max</sponsor> 
     <id>7</id> 
     <text>some text</text> 
    </amendment> 
</root> 

注意:從以前的答案的性差異是默認的空節點集表達式這些規則中的參數是必要的。