簡體   English   中英

xslt 中的 For-Each 問題

[英]Issue with For-Each in xslt

鑒於 xml:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
  <Interchange>
    <Group>
      <Message>
        <Loop2000>
          <Loop2300>
            <K3>
              <F449>BlaBlaBla</F449>
            </K3> 
            <K3>
              <F449>IEHPTraceID_123456</F449>
            </K3>
          </Loop2300>
        </Loop2000>
      </Message>
    </Group>
  </Interchange>
</Envelope>

以及以下 xslt:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="xml" indent="yes" />
        <xsl:template match="/">
                <xsl:for-each select="Envelope/Interchange/Group/Message/Loop2000/Loop2300/K3">
                    <xsl:if test="substring(/Envelope/Interchange/Group/Message/Loop2000/Loop2300/K3/F449,1,11)='IEHPTraceID'">
                        <InboundDataXml>
                            <CustomAttributes>
                                 <CustomAttribute>
                                    <AttributeName>Trace Id</AttributeName>
                                    <AttributeValue><xsl:value-of select="/Envelope/Interchange/Group/Message/Loop2000/Loop2300/K3/F449" /></AttributeValue>
                                 </CustomAttribute>
                            </CustomAttributes>
                        </InboundDataXml>
                    </xsl:if>
                </xsl:for-each>
        </xsl:template>
</xsl:transform>

我期望結果是:

<InboundDataXml>
   <CustomAttributes>
      <CustomAttribute>
         <AttributeName>Trace Id</AttributeName>
         <AttributeValue>IEHPTraceID_123456</AttributeValue>
      </CustomAttribute>
   </CustomAttributes>
</InboundDataXml>

顯然,我的 for-each 存在問題,因為我認為它會看到正確的節點,而 output 會看到預期的結果,但這並沒有發生。 如果我刪除第一個節點,我會得到預期的結果。 有人可以引導我朝着正確的方向前進嗎

請嘗試以下 XSLT。

xsl:for-each循環內,上下文是K3元素的所有子節點。 無需在 XPath 表達式中再次從根開始。

XSLT

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

    <xsl:template match="/">
        <xsl:for-each select="Envelope/Interchange/Group/Message/Loop2000/Loop2300/K3">
            <xsl:if test="substring(F449,1,11)='IEHPTraceID'">
                <InboundDataXml>
                    <CustomAttributes>
                        <CustomAttribute>
                            <AttributeName>Trace Id</AttributeName>
                            <AttributeValue>
                                <xsl:value-of select="F449"/>
                            </AttributeValue>
                        </CustomAttribute>
                    </CustomAttributes>
                </InboundDataXml>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Output

<?xml version='1.0' ?>
<InboundDataXml>
  <CustomAttributes>
    <CustomAttribute>
      <AttributeName>Trace Id</AttributeName>
      <AttributeValue>IEHPTraceID_123456</AttributeValue>
    </CustomAttribute>
  </CustomAttributes>
</InboundDataXml>

使用 xsl:for-each 時,上下文將更改為所選元素。 所以在循環內部,上下文是帶有子元素 F449 的 K3。 所以你可以像這樣直接測試那個孩子:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="/">
    <xsl:for-each select="Envelope/Interchange/Group/Message/Loop2000/Loop2300/K3">
      <xsl:if test="substring(F449,1,11)='IEHPTraceID'">
        <InboundDataXml>
          <CustomAttributes>
            <CustomAttribute>
              <AttributeName>Trace Id</AttributeName>
              <AttributeValue><xsl:value-of select="F449" /></AttributeValue>
            </CustomAttribute>
          </CustomAttributes>
        </InboundDataXml>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:transform>

您可以通過使用謂詞而不使用 xsl:if 來獲得相同的效果,如下所示:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="/">
    <xsl:for-each select="Envelope/Interchange/Group/Message/Loop2000/Loop2300/K3[substring(F449,1,11)='IEHPTraceID']">
      <InboundDataXml>
        <CustomAttributes>
          <CustomAttribute>
            <AttributeName>Trace Id</AttributeName>
            <AttributeValue><xsl:value-of select="F449" /></AttributeValue>
          </CustomAttribute>
        </CustomAttributes>
      </InboundDataXml>
    </xsl:for-each>
  </xsl:template>
</xsl:transform>

作為 xsl:foreach 的替代方案,您也可以這樣做:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  
  <xsl:template match="K3"/>
    
  <xsl:template match="K3[substring(F449,1,11)='IEHPTraceID']">
    <InboundDataXml>
      <CustomAttributes>
        <CustomAttribute>
          <AttributeName>Trace Id</AttributeName>
          <AttributeValue><xsl:value-of select="F449" /></AttributeValue>
        </CustomAttribute>
      </CustomAttributes>
    </InboundDataXml>
  </xsl:template>
</xsl:transform>

暫無
暫無

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

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