xml - XSLT 层次结构转换中的重复项
问题描述
我是论坛的新手,所以请原谅我的风格和语言不是英语的一些错误。我的问题是我有一个来自 db 上的选择的 xml 输出,我想通过 xslt 在分层结构上转换这个平面结构。我的 xslt 工作正常并正确执行层次结构,但存在复制所有项目并使其复制根元素的问题 这是 db 上 select 的 xml 输出:
<cdcDbSet xmlns="http://eos.mcr.com/cdc/anagrafica/ds">
<cdcEntity>
<idCdc>17</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>testGP</cdcName>
<order>1</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>15</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Caserta</cdcName>
<order>1</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>5</idCdc>
<idCdcParent>2</idCdcParent>
<cdcName>Progetti</cdcName>
<order>2</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>16</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>testGP</cdcName>
<order>2</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>18</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>testGPS</cdcName>
<order>2</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>11</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>figlio</cdcName>
<order>2</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>10</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>pippo</cdcName>
<order>3</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>6</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>EOS</cdcName>
<order>3</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>3</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Milano</cdcName>
<order>4</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>7</idCdc>
<idCdcParent>3</idCdcParent>
<cdcName>l</cdcName>
<order>4</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>14</idCdc>
<idCdcParent>15</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>8</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>pippo</cdcName>
<order>5</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>4</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Napoli</cdcName>
<order>5</order>
<isUsed>false</isUsed>
</cdcEntity>
<cdcEntity>
<idCdc>9</idCdc>
<idCdcParent>4</idCdcParent>
<cdcName>cccc</cdcName>
<order>6</order>
<isUsed>false</isUsed>
</cdcEntity>
</cdcDbSet>
这是 xslt:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds" version="1.0">
<xsl:key match="/nsc:cdcDbSet/nsc:cdcEntity" name="nodeChildren" use="nsc:idCdcParent"/>
<xsl:variable name="root" select="/nsc:cdcDbSet/nsc:cdcEntity/nsc:idCdcParent"/>
<xsl:template match="nsc:cdcDbSet">
<cdcList xmlns="http://ws.apache.org/ns/synapse">
<xsl:apply-templates select="nsc:cdcEntity[nsc:idCdcParent=$root]"/>
</cdcList>
</xsl:template>
<xsl:template match="nsc:cdcEntity">
<cdc xmlns="http://ws.apache.org/ns/synapse">
<idCdc>
<xsl:value-of select="nsc:idCdc"/>
</idCdc>
<idCdcParent>
<xsl:value-of select="nsc:idCdcParent"/>
</idCdcParent>
<cdcName>
<xsl:value-of select="nsc:cdcName"/>
</cdcName>
<order>
<xsl:value-of select="nsc:order"/>
</order>
<isUsed>
<xsl:value-of select="nsc:isUsed"/>
</isUsed>
<cdcList>
<xsl:apply-templates select="key('nodeChildren',nsc:idCdc)"/>
</cdcList>
</cdc>
</xsl:template>
</xsl:stylesheet>
这是转换后的 xml:
<cdcList xmlns="http://ws.apache.org/ns/synapse"
xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds">
<cdc>
<idCdc>17</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>testGP</cdcName>
<order>1</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>15</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Caserta</cdcName>
<order>1</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>14</idCdc>
<idCdcParent>15</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>5</idCdc>
<idCdcParent>2</idCdcParent>
<cdcName>Progetti</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>17</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>testGP</cdcName>
<order>1</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>18</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>testGPS</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>6</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>EOS</cdcName>
<order>3</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>16</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>testGP</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>18</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>testGPS</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>11</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>figlio</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>10</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>pippo</cdcName>
<order>3</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>6</idCdc>
<idCdcParent>5</idCdcParent>
<cdcName>EOS</cdcName>
<order>3</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>3</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Milano</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>7</idCdc>
<idCdcParent>3</idCdcParent>
<cdcName>l</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>7</idCdc>
<idCdcParent>3</idCdcParent>
<cdcName>l</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>14</idCdc>
<idCdcParent>15</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>8</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>pippo</cdcName>
<order>5</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>4</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Napoli</cdcName>
<order>5</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>9</idCdc>
<idCdcParent>4</idCdcParent>
<cdcName>cccc</cdcName>
<order>6</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>9</idCdc>
<idCdcParent>4</idCdcParent>
<cdcName>cccc</cdcName>
<order>6</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
如您所见,有些项目重复,我想将其删除。例如,idCdc=17 的项目 cdc 位于 cdcList 下,而 idCdc=5 的 cdc 下我尝试修改 xslt,但没有得到很好的结果。感谢大家尝试帮助我。
Ps:我希望看到这样的东西:
<cdcList xmlns="http://ws.apache.org/ns/synapse" xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds">
<cdc>
<idCdc>1</idCdc>
<idCdcParent>0</idCdcParent>
<cdcName>Roma</cdcName>
<order>1</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>4</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>5</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>6</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>7</idCdc>
<idCdcParent>6</idCdcParent>
<cdcName>testMODChild</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>2</idCdc>
<idCdcParent>0</idCdcParent>
<cdcName>Progetti</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>8</idCdc>
<idCdcParent>2</idCdcParent>
<cdcName>testGP</cdcName>
<order>1</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>9</idCdc>
<idCdcParent>2</idCdcParent>
<cdcName>testGPS</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>10</idCdc>
<idCdcParent>2</idCdcParent>
<cdcName>EOS</cdcName>
<order>3</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>3</idCdc>
<idCdcParent>0</idCdcParent>
<cdcName>Milano</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>11</idCdc>
<idCdcParent>3</idCdcParent>
<cdcName>l</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
</cdcList>
解决方案
你的错误在这里:
<xsl:variable name="root" select="/nsc:cdcDbSet/nsc:cdcEntity/nsc:idCdcParent"/>
这不会选择单个节点,更不用说根节点,甚至是根节点的ID。
它选择所有 <nsc:idCdcParent>
元素。连同这个
<xsl:apply-templates select="nsc:cdcEntity[nsc:idCdcParent=$root]"/>
where [nsc:idCdcParent=$root]
always 为真,因为所有<nsc:idCdcParent>
都在 中$root
,并且递归步骤
<xsl:apply-templates select="key('nodeChildren',nsc:idCdc)"/>
您多次浏览输入文档,导致重复输出。
假设根节点的 ID 为 1,这将生成一个正确嵌套的树。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds"
xmlns="http://ws.apache.org/ns/synapse"
exclude-result-prefixes="nsc"
>
<xsl:output indent="yes" />
<xsl:key name="nodesByParent" match="nsc:cdcEntity" use="nsc:idCdcParent"/>
<xsl:template match="nsc:cdcDbSet">
<cdcList>
<xsl:apply-templates select="key('nodesByParent', 1)"/>
</cdcList>
</xsl:template>
<xsl:template match="nsc:cdcEntity">
<cdc>
<xsl:apply-templates mode="copy-local" select="
nsc:idCdc|nsc:idCdcParent|nsc:cdcName|nsc:order|nsc:isUsed
" />
<cdcList>
<xsl:apply-templates select="key('nodesByParent', nsc:idCdc)"/>
</cdcList>
</cdc>
</xsl:template>
<xsl:template match="*" mode="copy-local">
<xsl:element name="{local-name()}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
笔记
- 顶级默认
xmlns
声明,因此您无需在样式表正文中重复自己 exclude-result-prefixes
属性_- 通过使用模板输出具有相同本地名称的任何元素来减少重复
结果:
<cdcList xmlns="http://ws.apache.org/ns/synapse">
<cdc>
<idCdc>15</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Caserta</cdcName>
<order>1</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>14</idCdc>
<idCdcParent>15</idCdcParent>
<cdcName>testMOD</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>16</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>testGP</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>11</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>figlio</cdcName>
<order>2</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>10</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>pippo</cdcName>
<order>3</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>3</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Milano</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>7</idCdc>
<idCdcParent>3</idCdcParent>
<cdcName>l</cdcName>
<order>4</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
<cdc>
<idCdc>8</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>pippo</cdcName>
<order>5</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
<cdc>
<idCdc>4</idCdc>
<idCdcParent>1</idCdcParent>
<cdcName>Napoli</cdcName>
<order>5</order>
<isUsed>false</isUsed>
<cdcList>
<cdc>
<idCdc>9</idCdc>
<idCdcParent>4</idCdcParent>
<cdcName>cccc</cdcName>
<order>6</order>
<isUsed>false</isUsed>
<cdcList/>
</cdc>
</cdcList>
</cdc>
</cdcList>
推荐阅读
- python - Tweepy 自动运行
- java - 无法导入 io.quarkus.elasticsearch.restclient.lowlevel.ElasticsearchClientConfig
- c# - Null Reference instance Object GameObject.FindWithTag("Player").transform.parent = Level Unity
- c# - 使用框架和页面时如何使窗口透明?
- python - Selenium 在同一网站上打开了数千个链接,被 Captcha 检测到
- git - 如何使用 git 更新应用程序的 200 个实例
- python - 我不明白 plt.show()... 做了什么
- forms - 在后端使用 DOMPurify 来清理表单数据的错误?
- mysql - MySQL 更新不支持索引条件下推?
- javascript - 在 php 中定义一个外部 javascript 函数