XSLT foreach与递归相结合

时间:2015-01-09 09:40:11

标签: xml xslt recursion foreach

我需要将foreach与我在XSLT中编写的递归解决方案结合起来。 问题写在下面。当你从上到下阅读这篇文章时会更清楚。

这是一个XML示例(原始XML要大得多):

XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <GetAllResponse xmlns="z">
            <GetAllResult xmlns:i="y" xmlns:a="x">
                <a:OrganisatieEenheden>              
                    <a:OrganisatieEenheid>
                        <a:Code>1</a:Code>
                        <a:Omschrijving>Niveau1</a:Omschrijving>
                        <a:OrganisatieEenheidCrsNr>1001</a:OrganisatieEenheidCrsNr>
                        <a:ParentCode i:nil="true"/>
                    </a:OrganisatieEenheid>              
                    <a:OrganisatieEenheid>
                        <a:Code>2</a:Code>
                        <a:Omschrijving>Niveau2</a:Omschrijving>
                        <a:OrganisatieEenheidCrsNr>1002</a:OrganisatieEenheidCrsNr>
                        <a:ParentCode>1</a:ParentCode>
                    </a:OrganisatieEenheid>     
                    <a:OrganisatieEenheid>
                        <a:Code>8</a:Code>
                        <a:Omschrijving>Niveau8</a:Omschrijving>
                        <a:OrganisatieEenheidCrsNr>1008</a:OrganisatieEenheidCrsNr>
                        <a:ParentCode i:nil="true"/>
                    </a:OrganisatieEenheid>             
                    <a:OrganisatieEenheid>
                        <a:Code>3</a:Code>
                        <a:Omschrijving>Niveau3</a:Omschrijving>
                        <a:OrganisatieEenheidCrsNr>1003</a:OrganisatieEenheidCrsNr>
                        <a:ParentCode>2</a:ParentCode>
                    </a:OrganisatieEenheid>
                    <a:OrganisatieEenheid>
                        <a:Code>4</a:Code>
                        <a:Omschrijving>Niveau4</a:Omschrijving>
                        <a:OrganisatieEenheidCrsNr>1004</a:OrganisatieEenheidCrsNr>
                        <a:ParentCode>3</a:ParentCode>
                    </a:OrganisatieEenheid>
                </a:OrganisatieEenheden>
            </GetAllResult>
        </GetAllResponse>
    </soapenv:Body>
</soapenv:Envelope>

递归XSLT (有关递归的其他信息可以在本文的底部找到)

<?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                   xmlns:i="y"
                   xmlns:a="x"
                   version="1.0"
                   exclude-result-prefixes="a i">
      <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
      <xsl:param name="crs" select="1004"/>
      <xsl:key name="org-by-crs"
               match="a:OrganisatieEenheid"
               use="a:OrganisatieEenheidCrsNr"/>
      <xsl:key name="org-by-code" match="a:OrganisatieEenheid" use="a:Code"/>
      <xsl:template match="/">
         <OrganisatieEenheid>
            <Niveaus>
               <xsl:apply-templates select="key('org-by-crs', $crs)"/>
            </Niveaus>
            <OrganisatieEenheidCrsNr>
               <xsl:value-of select="$crs"/>
            </OrganisatieEenheidCrsNr>
         </OrganisatieEenheid>
      </xsl:template>
      <xsl:template match="a:OrganisatieEenheid">
         <xsl:if test="a:ParentCode[not(@i:nil='true')]">
            <xsl:apply-templates select="key('org-by-code', a:ParentCode)"/>
            <xsl:text>::</xsl:text>
         </xsl:if>
         <xsl:value-of select="a:Omschrijving"/>
      </xsl:template>
   </xsl:stylesheet>

输出递归XSLT

<?xml version="1.0" encoding="utf-8"?>
<OrganisatieEenheid>
   <Niveaus>Niveau1::Niveau2::Niveau3::Niveau4</Niveaus>
   <OrganisatieEenheidCrsNr>1004</OrganisatieEenheidCrsNr>
</OrganisatieEenheid>

我也写了foreach函数,它取了所有的a:OrganisatieEenheidCrsNr

foreach XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                   xmlns:i="y"
                   xmlns:a="x"
                   xmlns:ns2="z"
                   version="1.0"
                   exclude-result-prefixes="a i">
    <xsl:template match="/">
        <xsl:for-each select="//ns2:GetAllResponse/ns2:GetAllResult/a:OrganisatieEenheden/a:OrganisatieEenheid">
            <xsl:value-of select="a:OrganisatieEenheidCrsNr"/>  
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

输出foreach XSLT

<?xml version="1.0" encoding="UTF-8"?>10011002100810031004

问题

在递归函数中,我给出了a:OrganisatieEenheidCrsNr,这将导致1个结果。 现在我需要一个解决方案,为XML中的每一个:OrganisatieEenheidCrsNr执行此操作。 所以我想我必须遍历所有数字并对每个数字执行递归。

解决方案我需要上面的XML示例

<?xml version="1.0" encoding="utf-8"?>
<OrganisatieEenheden>
    <OrganisatieEenheid>
       <Niveaus>Niveau1</Niveaus>
       <OrganisatieEenheidCrsNr>1001</OrganisatieEenheidCrsNr>
    </OrganisatieEenheid>
    <OrganisatieEenheid>
       <Niveaus>Niveau1::Niveau2</Niveaus>
       <OrganisatieEenheidCrsNr>1002</OrganisatieEenheidCrsNr>
    </OrganisatieEenheid>
    <OrganisatieEenheid>
       <Niveaus>Niveau8</Niveaus>
       <OrganisatieEenheidCrsNr>1008</OrganisatieEenheidCrsNr>
    </OrganisatieEenheid>
    <OrganisatieEenheid>
       <Niveaus>Niveau1::Niveau2::Niveau3</Niveaus>
       <OrganisatieEenheidCrsNr>1003</OrganisatieEenheidCrsNr>
    </OrganisatieEenheid>
    <OrganisatieEenheid>
       <Niveaus>Niveau1::Niveau2::Niveau3::Niveau4</Niveaus>
       <OrganisatieEenheidCrsNr>1004</OrganisatieEenheidCrsNr>
    </OrganisatieEenheid>
</OrganisatieEenheden>

有关递归的其他信息

输入:OrganisatieEenheidCrsNr - &gt; 1004 a:ParentCode和a:代码是父子关系

当您的输入为1004时,它会搜索其他父母,直到a:ParentCode i:nil =“true”。 然后打印所有Niveaus从顶部过半底部分隔::并打印输入值。

方便的工具:http://xslttest.appspot.com/

感谢您和我一起思考!

1 个答案:

答案 0 :(得分:0)

不,你不需要任何循环。

目前,您将(完全正确的)构造应用于一个案例。您只需将其应用于所有个案。这意味着:摆脱变量,你就完成了。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:i="y"
    xmlns:a="x"
    exclude-result-prefixes="a i"
>
  <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:key name="org-by-crs" match="a:OrganisatieEenheid" use="a:OrganisatieEenheidCrsNr"/>
  <xsl:key name="org-by-code" match="a:OrganisatieEenheid" use="a:Code"/>

  <xsl:template match="a:OrganisatieEenheden">
    <OrganisatieEenheden>
      <xsl:apply-templates select="a:OrganisatieEenheid" />
    </OrganisatieEenheden>
  </xsl:template>

  <xsl:template match="a:OrganisatieEenheid">
    <OrganisatieEenheid>
      <Niveaus>
        <xsl:apply-templates select="key('org-by-crs', a:OrganisatieEenheidCrsNr)" mode="niveaus" />
      </Niveaus>
      <OrganisatieEenheidCrsNr>
        <xsl:value-of select="a:OrganisatieEenheidCrsNr" />
      </OrganisatieEenheidCrsNr>
    </OrganisatieEenheid>
  </xsl:template>

  <xsl:template match="a:OrganisatieEenheid" mode="niveaus">
    <xsl:if test="a:ParentCode[not(@i:nil='true')]">
      <xsl:apply-templates select="key('org-by-code', a:ParentCode)" mode="niveaus" />
      <xsl:text>::</xsl:text>
    </xsl:if>
    <xsl:value-of select="a:Omschrijving" />
  </xsl:template>
</xsl:stylesheet>

结果:

<OrganisatieEenheden>
   <OrganisatieEenheid>
      <Niveaus>Niveau1</Niveaus>
      <OrganisatieEenheidCrsNr>1001</OrganisatieEenheidCrsNr>
   </OrganisatieEenheid>
   <OrganisatieEenheid>
      <Niveaus>Niveau1::Niveau2</Niveaus>
      <OrganisatieEenheidCrsNr>1002</OrganisatieEenheidCrsNr>
   </OrganisatieEenheid>
   <OrganisatieEenheid>
      <Niveaus>Niveau8</Niveaus>
      <OrganisatieEenheidCrsNr>1008</OrganisatieEenheidCrsNr>
   </OrganisatieEenheid>
   <OrganisatieEenheid>
      <Niveaus>Niveau1::Niveau2::Niveau3</Niveaus>
      <OrganisatieEenheidCrsNr>1003</OrganisatieEenheidCrsNr>
   </OrganisatieEenheid>
   <OrganisatieEenheid>
      <Niveaus>Niveau1::Niveau2::Niveau3::Niveau4</Niveaus>
      <OrganisatieEenheidCrsNr>1004</OrganisatieEenheidCrsNr>
   </OrganisatieEenheid>
</OrganisatieEenheden>