XSLT foreach 结合递归
XSLT foreach combined with recursion
我需要将 foreach 与我用 XSLT 编写的递归解决方案相结合。
问题写在下面。这个post从上往下看会更清楚
这是一个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
(有关递归的其他信息可以在此 post 的底部找到)
<?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>
每个 XSLT 的输出
<?xml version="1.0" encoding="UTF-8"?>10011002100810031004
问题
在递归函数中,我给出了 a:OrganisatieEenheidCrsNr,这将导致 1 个结果。
现在我需要一个解决方案来为 XML 中的每个 a: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 -> 1004
a:ParentCode 和 a:Code 是 Parent - Child 关系
当您输入 1004 时,它会搜索所有 parents 直到 a:ParentCode i:nil="true"。
然后从上到下打印所有由 :: 分隔的 Niveaus,并打印输入值。
得心应手的工具:http://xslttest.appspot.com/
谢谢你和我一起思考!
不,您不需要任何循环。
目前您将您的(完全正确的)结构应用于一个案例。您只需要将其应用于 所有 个案例。这意味着:摆脱变量,你就完成了。
<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>
我需要将 foreach 与我用 XSLT 编写的递归解决方案相结合。 问题写在下面。这个post从上往下看会更清楚
这是一个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 (有关递归的其他信息可以在此 post 的底部找到)
<?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>
每个 XSLT 的输出
<?xml version="1.0" encoding="UTF-8"?>10011002100810031004
问题
在递归函数中,我给出了 a:OrganisatieEenheidCrsNr,这将导致 1 个结果。 现在我需要一个解决方案来为 XML 中的每个 a: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 -> 1004 a:ParentCode 和 a:Code 是 Parent - Child 关系
当您输入 1004 时,它会搜索所有 parents 直到 a:ParentCode i:nil="true"。 然后从上到下打印所有由 :: 分隔的 Niveaus,并打印输入值。
得心应手的工具:http://xslttest.appspot.com/
谢谢你和我一起思考!
不,您不需要任何循环。
目前您将您的(完全正确的)结构应用于一个案例。您只需要将其应用于 所有 个案例。这意味着:摆脱变量,你就完成了。
<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>