XSL Counter over flat XML

时间:2016-03-24 21:29:10

标签: xslt xslt-1.0

我正在尝试在以下源XML片段上维护一个序列号计数器。序列号位于目标OBX.1元素中。这是基于源中具有数据的元素NOS / POS / ROS。在此示例中,由于所有3个元素都有数据,因此序列1,2,3在OBX.1中生成。但是,如果任何NOS / POS / ROS为空,则不应生成相应的OBX节点,但其余元素应按正确的顺序排列。我可以通过将OBX.1设置为: count(preceding-sibling :: ns1:NOS [string-length(。)> 0] | preceding-sibling :: top:POS [string-length(。)> 0])+ 1但是当你的时候它会变得单调乏味有15个这样的元素。有没有更好的方法来维持这个计数器?

Source XML Snippet:

<ns1:HladtCollection xmlns:ns1="http://xmlns.oracle.com/pcbpel/adapter/db/top/ReadAdtHistorical">
        <ns1:Hladt>
            <ns1:ADTMessageID>123</ns1:ADTMessageID>
            <ns1:ADTMessageType>ADD</ns1:ADTMessageType>
            <ns1:AccountNumber>3456</ns1:AccountNumber>
            <ns1:ArrivalDate>2016-03-22T11:45:12.220000000</ns1:ArrivalDate>
            <ns1:NOS>Test1</ns1:NOS>
            <ns1:POS>Test2</ns1:POS>
            <ns1:ROS>Test3</ns1:ROS>
        </ns1:Hladt>
</ns1:HladtCollection>

目标XML代码段:

<ns1:OBX>
  <ns1:OBX.1>1</ns1:OBX.1>
  <ns1:OBX.2>ST</ns1:OBX.2>
  <ns1:OBX.3>
     <ns1:CE_OBS.1>
        <ns1:CM_OBS.1>122</ns1:CM_OBS.1>
     </ns1:CE_OBS.1>
  </ns1:OBX.3>
  <ns1:OBX.5>Test1</ns1:OBX.5>
</ns1:OBX>
<ns1:OBX>
  <ns1:OBX.1>2</ns1:OBX.1>
  <ns1:OBX.2>ST</ns1:OBX.2>
  <ns1:OBX.3>
     <ns1:CE_OBS.1>
        <ns1:CM_OBS.1>111</ns1:CM_OBS.1>
     </ns1:CE_OBS.1>
  </ns1:OBX.3>
  <ns1:OBX.5>Test2</ns1:OBX.5>
</ns1:OBX>
<ns1:OBX>
  <ns1:OBX.1>3</ns1:OBX.1>
  <ns1:OBX.2>ST</ns1:OBX.2>
  <ns1:OBX.3>
     <ns1:CE_OBS.1>
        <ns1:CM_OBS.1>222</ns1:CM_OBS.1>
     </ns1:CE_OBS.1>
  </ns1:OBX.3>
  <ns1:OBX.5>Test3</ns1:OBX.5>
</ns1:OBX>

1 个答案:

答案 0 :(得分:0)

好吧,如果您只选择NOSPOSROS元素,如果没有空,则可以使用position()函数,因为这会返回节点在所选节点集中的位置,而不是层次结构中的位置。例如

<xsl:for-each select="(ns1:NOS|ns1:POS|ns1:ROS)[. != '']">
    <ns1:OBX>
       <ns1:OBX.1><xsl:value-of select="position()" /> </ns1:OBX.1>
       <ns1:OBX.5><xsl:value-of select="." /></ns1:OBX.5>
    </ns1:OBX>
</xsl:for-each>

或者,您可以使用xsl:number

<xsl:for-each select="ns1:NOS|ns1:POS|ns1:ROS">
   <xsl:if test=". != ''">
      <ns1:OBX>
         <ns1:OBX.1><xsl:number count="ns1:NOS[. != '']|ns1:POS[. != '']|ns1:ROS[. != '']" /> </ns1:OBX.1>
          <ns1:OBX.5><xsl:value-of select="." /></ns1:OBX.5>
      </ns1:OBX>
   </xsl:if>
</xsl:for-each>