簡體   English   中英

XSLT:根據以下同級值返回結果

[英]XSLT: Return results based on following sibling value

我是XSLT的新手。 任何幫助,將不勝感激 ....

<Test>
  <loop loop_id="5" LoopElementOrder_no="1" Segment_id="3" >
     <usage_id>1</usage_id>
    <value>41</value>
  </loop>
  <loop loop_id="5" LoopElementOrder_no="2"  Segment_id="3">
    <usage_id>1</usage_id>
     <value>2</value>
      </loop>
  <loop loop_id="5" LoopElementOrder_no="4" Segment_id="3">
     <usage_id>2</usage_id>
     <value>raj</value>
      </loop>
  <loop loop_id="5" LoopElementOrder_no="5" Segment_id="3">
     <usage_id>3</usage_id>
      <value>d</value>
    </loop>
  <loop loop_id="5"  LoopElementOrder_no="6" Segment_id="3">
    <usage_id>3</usage_id>  
      <value>8</value>
  </loop>
  <loop loop_id="5"  LoopElementOrder_no="7" Segment_id="3">
    <usage_id>3</usage_id>
      <value>7</value>
  </loop>
  <loop loop_id="5" LoopElementOrder_no="1" Segment_id="4">
       <usage_id>1</usage_id>

    <value>IC</value>
      </loop>
  <loop loop_id="5"  LoopElementOrder_no="2" Segment_id="4">
  <usage_id>2</usage_id>
      <value>d</value> 
  </loop>
 <loop loop_id="5"  LoopElementOrder_no="3" Segment_id="4">
      <usage_id>3</usage_id>
          <value>dm</value> 
      </loop> 
 <loop loop_id="5"  LoopElementOrder_no="4" Segment_id="4">
      <usage_id>2</usage_id>
          <value>wj</value> 
      </loop> 
    </Test>

我只想返回'value',如果其usage_id為1或2。如果use_id為3,則應返回“ N / A”。 但是,例如,如果在Segment_id = 3 LoopElementOrder_no = 5中,則Segment_id = 3的其余部分不包含任何Usage_id為1或2,在這種情況下,我需要返回“ ^”,並使用LoopElementOrder_no從Segment_id = 4繼續進行操作= 1。

上面的期望輸出是:

41 2 raj ^IC d N/A wj

請嘗試一下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="loop">
    <xsl:value-of select="concat(value, ' ')"/>
  </xsl:template>

  <xsl:template match="loop[usage_id = 3]">
    <xsl:variable name="segmentId" select="@Segment_id" />
    <xsl:variable name="following12"
                  select="following-sibling::loop[@Segment_id = $segmentId]
                                                 [usage_id = 1 or usage_id = 2]" />
    <xsl:apply-templates
      select="current()[not(preceding-sibling::loop[1]
                                                   [@Segment_id = $segmentId]
                                                   [usage_id = 3])
                        and not($following12)]" mode="carat" />
    <xsl:apply-templates select="current()[$following12]" mode="na" />
  </xsl:template>

  <xsl:template match="loop" mode="na">
    <xsl:text>N/A </xsl:text>
  </xsl:template>

  <xsl:template match="loop" mode="carat">
    <xsl:text>^</xsl:text>
  </xsl:template>
</xsl:stylesheet>

在樣本輸入上運行時,結果為:

41 2 raj ^IC d N/A wj 

更短,更簡單的方法(只有三個模板,沒有xsl:apply-templates ,沒有xsl:variable ,沒有current() ,也沒有模式),並且更容易理解,完全采用“推送樣式”:

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

 <xsl:template match="loop[not(usage_id >2)]">
  <xsl:value-of select="concat(value, ' ')"/>
 </xsl:template>

 <xsl:template match=
 "loop[usage_id = 3
     and preceding-sibling::loop[not(usage_id >2)][1]/@Segment_id
        =following-sibling::loop[not(usage_id >2)][1]/@Segment_id
      ]
 ">N/A </xsl:template>

 <xsl:template match=
 "loop
   [usage_id >2
  and
    preceding-sibling::loop[1][not(usage_id >2)]
  and
    not(@Segment_id =following-sibling::loop[not(usage_id >2)][1]/@Segment_id)
    ]">^ </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

在提供的XML文檔上應用此轉換時:

<Test>
  <loop loop_id="5" LoopElementOrder_no="1" Segment_id="3" >
     <usage_id>1</usage_id>
    <value>41</value>
  </loop>
  <loop loop_id="5" LoopElementOrder_no="2"  Segment_id="3">
    <usage_id>1</usage_id>
     <value>2</value>
      </loop>
  <loop loop_id="5" LoopElementOrder_no="4" Segment_id="3">
     <usage_id>2</usage_id>
     <value>raj</value>
      </loop>
  <loop loop_id="5" LoopElementOrder_no="5" Segment_id="3">
     <usage_id>3</usage_id>
      <value>d</value>
    </loop>
  <loop loop_id="5"  LoopElementOrder_no="6" Segment_id="3">
    <usage_id>3</usage_id>
      <value>8</value>
  </loop>
  <loop loop_id="5"  LoopElementOrder_no="7" Segment_id="3">
    <usage_id>3</usage_id>
      <value>7</value>
  </loop>
  <loop loop_id="5" LoopElementOrder_no="1" Segment_id="4">
       <usage_id>1</usage_id>

    <value>IC</value>
      </loop>
  <loop loop_id="5"  LoopElementOrder_no="2" Segment_id="4">
  <usage_id>2</usage_id>
      <value>d</value>
  </loop>
 <loop loop_id="5"  LoopElementOrder_no="3" Segment_id="4">
      <usage_id>3</usage_id>
          <value>dm</value>
      </loop>
 <loop loop_id="5"  LoopElementOrder_no="4" Segment_id="4">
      <usage_id>2</usage_id>
          <value>wj</value>
      </loop>
</Test>

所需的正確結果產生了:

41 2 raj ^ IC d N/A wj

更新

該解決方案可以進一步簡化和簡化:

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

 <xsl:template match="loop[not(usage_id >2)]">
   <xsl:if test=
   "preceding-sibling::loop[not(usage_id >2)][1]
      [not(@Segment_id = current()/@Segment_id)]">^ </xsl:if>
   <xsl:value-of select="concat(value, ' ')"/>
 </xsl:template>

 <xsl:template match=
 "loop[usage_id = 3
     and preceding-sibling::loop[not(usage_id >2)][1]/@Segment_id
        =following-sibling::loop[not(usage_id >2)][1]/@Segment_id
      ]
 ">N/A </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

暫無
暫無

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

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