2017-09-01 49 views
0

我有下面的XML访问分组节点使用XPath建立一个恒定的输出

<toPay> 
<Pay> 
    <amount>1111</amount>  
    <accountNumber>223128987</accountNumber> 
    <payType>PAYROLL</payType> 
</Pay> 
<Pay> 
    <amount>2222</amount> 
    <accountNumber>123128987</accountNumber> 
    <payType>PAYROLL</payType> 
</Pay> 
<Pay> 
    <amount>333</amount> 
    <accountNumber>645032</accountNumber> 
    <payType>MAIN</payType> 
</Pay> 

我需要按此格式输出:

<root> 
<element> 
    <amount>1111</amount> 
    <accountNumber>223128987</accountNumber> 
</element> 
<element> 
    <amount>2222</amount> 
    <accountNumber>223128987</accountNumber> 
</element> 
<element> 
    <amount></amount> 
    <accountNumber></accountNumber> 
</element> 
<element> 
    <amount></amount> 
    <accountNumber></accountNumber> 
</element> 

我写了如下代码:

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

<xsl:key name="groups" match="payType" use="." /> 

<xsl:template match="/toPay/Pay"> 
    <root> 
     <xsl:apply-templates select="payType[generate-id() = generate-id(key('groups', .)[1])]" /> 
    </root> 
</xsl:template> 

<xsl:template match="payType"> 
    <xsl:variable name="currentGroup" select="." /> 
     <xsl:if test="$currentGroup = 'PAYROLL'"> 

      <xsl:for-each select="key('groups', $currentGroup)"> 
       <element> 
        <xsl:if test="position() = 1"> 
         <amount> 
          <xsl:value-of select="../amount" /> 
         </amount> 
         <accountNumber> 
          <xsl:value-of select="../accountNumber" /> 
         </accountNumber> 
        </xsl:if>     
        <xsl:if test="position() = 2"> 
         <amount> 
          <xsl:value-of select="../amount" /> 
         </amount> 
         <accountNumber> 
          <xsl:value-of select="../accountNumber" /> 
         </accountNumber> 
        </xsl:if> 
       </element> 
      </xsl:for-each> 
     </xsl:if> 
</xsl:template> 

但我面临的问题是 - 我不能访问分组节点为paytype -PAYROLL。我知道的唯一方法是使用位置,但是我的要求始终在输出中始终输入4个元素节点,而无论源xml中带有PAYtype -PAYROLL的节点是否存在。 如果存在,那么将填充相同eeds的值,如果不存在,那么xml标签将不带值。

任何帮助非常感谢 - 无论是xslt 1.0或2.0。

+0

请用单词解释所需的逻辑。我根本不理解你的输出。 –

+0

您的模板会创建一个“组”结果元素,而您所需的输出不会显示任何此类元素。所以你需要更详细地解释你想要实现的内容。在完整结果中,每个“组”或“元素”结果元素中是否需要四个'element'元素? –

+0

在输出中应该总是有4个元素节点。每个元素节点都应该使用来自源xml节点的值来填充payType,其中payType是PAYROLL。如果Pay支付节点的PayType为PayPoll,那么输出应该有前2个元素节点,其值来自xml源,其余2个元素节点的x值和账户数量为空值。 – Vicky

回答

1

如果我理解正确的话你的解释,你可以做一些非常简单的 - 即使有点原始:

<xsl:template match="/toPay"> 
    <xsl:variable name="payroll" select="Pay[payType='PAYROLL']" /> 
    <root> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[1]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[1]/accountNumber" />   
      </accountNumber> 
     </element> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[2]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[2]/accountNumber" />   
      </accountNumber> 
     </element> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[3]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[3]/accountNumber" />   
      </accountNumber> 
     </element> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[4]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[4]/accountNumber" />   
      </accountNumber> 
     </element> 
    </root> 
</xsl:template> 

我看到的东西分组没有要求。


这里有一个稍微优雅版:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/toPay"> 
    <xsl:variable name="payroll" select="Pay[payType='PAYROLL']" /> 
    <root> 
     <xsl:apply-templates select="$payroll"/> 
     <xsl:for-each select="1 to 4 - count($payroll)"> 
      <element> 
       <amount/> 
       <accountNumber/> 
       </element> 
     </xsl:for-each> 
    </root> 
</xsl:template> 

<xsl:template match="Pay"> 
    <element> 
     <xsl:copy-of select="amount, accountNumber"/> 
    </element> 
</xsl:template> 

</xsl:stylesheet> 

演示:http://xsltransform.net/6pS1zDr

+0

为我工作谢谢 – Vicky

+0

@Vicky如果您的问题得到解答,请通过接受答案关闭它。 –

1

我也认为没有必要进行分组,如果你想输出空这些元素的元素不会出现在XSLT 2.0中,您可以使用

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:output indent="yes"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="toPay"> 
     <root> 
      <xsl:variable name="payroll" select="Pay[payType = 'PAYROLL']"/> 
      <xsl:apply-templates select="$payroll"/> 
      <xsl:for-each select="(count($payroll) + 1) to 4"> 
       <element> 
       <amount></amount> 
       <accountNumber></accountNumber> 
      </element> 
      </xsl:for-each> 
     </root> 
    </xsl:template> 

    <xsl:template match="Pay"> 
     <element> 
      <xsl:apply-templates select="* except payType"/> 
     </element> 
    </xsl:template> 
</xsl:transform> 
相关问题