2010-12-07 6 views
1

Ich muss in ein Element die <sectionid/>, <amendmenttext/> und <sponsor/> Elemente ziehen, wenn verfügbar. Hierletzte Gruppe der vorherigen Geschwister erhalten mit XSLT

ein Beispiel:

Von:

<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> 

zu:

<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> 

Anmerkung 1: Das <sectionid/> Element gilt für alle <amendments/> vor dem nächsten <sectionid/>

Anmerkung 2: die <sponsor/> Element gilt für alle <amendments/> vor der nächsten <sponsor/> Liste.

Hinweis 3: Die Werte //amendment/id sind nicht sequenziell.

Hinweis 4: Ein konnte keine <sponsor/> oder <sectionid/> als Vorgänger-Geschwister haben.

Note 5: <amendmenttext> gilt nur für die folgenden <amendment/>

Wie diese Transformation mit XSLT 1.0 getan werden kann.

+0

Änderungen von der vorherigen Frage http://StackOverflow.com/Questions/4096481/Refactor-XML-with-xsl ist eine Minderjährige. Ich denke nicht, dass es eine neue Frage verdient. –

+0

Oki. Nicht wissen, dass die Lösung ähnlich wäre. Ich dachte, es sei nicht fair gegenüber den ursprünglichen Respondern, den Kontext der Frage zu ändern, nachdem sie geantwortet hatten. Aber Punkt genommen. –

Antwort

2

Dieses Stylesheet (die gleiche Antwort als zuvor, aber nur eine Regel):

<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> 

Ausgang:

<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> 

Hinweis: Die diference aus früheren Antwort ist der Standard leer Knotensatz Ausdruck für Parameter in diesen Regeln, die benötigt werden.

+0

@Alejandro, ich habe einfach zur Beispiel-XML hinzugefügt. –

+0

@Benjamin Ortuzar: An diesem Punkt sollten Sie wissen, wie Sie diese oder vorherige Antwort entsprechend ändern können. Sehen wir uns die Änderungen in diesem Stylesheet an: fügen Sie den Parameter 'pAmentmentText' mit dem leeren Knotensatz'/.. 'als defaut-Wert hinzu, fügen Sie die Variable' vAmentmentText' als 'self :: amendmenttest' hinzu, fügen Sie diese Variable zum' xsl: if/@ hinzu test 'zum Überspringen der Kopie, fügen Sie eine 'xsl: copy-of'-Anweisung mit' $ pAmentmentText [$ vAmendment] 'hinzu, übergeben Sie einen' pAmentmentText' -Parameter mit '$ pAmentmentText [not ($ vAvendment)] | $ vAmentmentText' –

Verwandte Themen