如何在 XSL 中防止重复? [英] How do I prevent duplicates, in XSL?
问题描述
如何防止重复条目进入列表,然后理想地对该列表进行排序?我正在做的是,当一个级别的信息丢失时,从它下面的一个级别获取信息,在上面的级别构建丢失的列表.目前,我有类似这样的 XML:
How do I prevent duplicate entries into a list, and then ideally, sort that list? What I'm doing, is when information at one level is missing, taking the information from a level below it, to building the missing list, in the level above. Currently, I have XML similar to this:
<c03 id="ref6488" level="file">
<did>
<unittitle>Clinic Building</unittitle>
<unitdate era="ce" calendar="gregorian">1947</unitdate>
</did>
<c04 id="ref34582" level="file">
<did>
<container label="Box" type="Box">156</container>
<container label="Folder" type="Folder">3</container>
</did>
</c04>
<c04 id="ref6540" level="file">
<did>
<container label="Box" type="Box">156</container>
<unittitle>Contact prints</unittitle>
</did>
</c04>
<c04 id="ref6606" level="file">
<did>
<container label="Box" type="Box">154</container>
<unittitle>Negatives</unittitle>
</did>
</c04>
</c03>
然后我应用以下 XSL:
I then apply the following XSL:
<xsl:template match="c03/did">
<xsl:choose>
<xsl:when test="not(container)">
<did>
<!-- If no c03 container item is found, look in the c04 level for one -->
<xsl:if test="../c04/did/container">
<!-- If a c04 container item is found, use the info to build a c03 version -->
<!-- Skip c03 container item, if still no c04 items found -->
<container label="Box" type="Box">
<!-- Build container list -->
<!-- Test for more than one item, and if so, list them, -->
<!-- separated by commas and a space -->
<xsl:for-each select="../c04/did">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="container"/>
</xsl:for-each>
</container>
</did>
</xsl:when>
<!-- If there is a c03 container item(s), list it normally -->
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
但我得到的容器"结果是
But I'm getting the "container" result of
<container label="Box" type="Box">156, 156, 154</container>
当我想要的时候
<container label="Box" type="Box">154, 156</container>
下面是我想要得到的完整结果:
Below is the full result that I'm trying to get:
<c03 id="ref6488" level="file">
<did>
<container label="Box" type="Box">154, 156</container>
<unittitle>Clinic Building</unittitle>
<unitdate era="ce" calendar="gregorian">1947</unitdate>
</did>
<c04 id="ref34582" level="file">
<did>
<container label="Box" type="Box">156</container>
<container label="Folder" type="Folder">3</container>
</did>
</c04>
<c04 id="ref6540" level="file">
<did>
<container label="Box" type="Box">156</container>
<unittitle>Contact prints</unittitle>
</did>
</c04>
<c04 id="ref6606" level="file">
<did>
<container label="Box" type="Box">154</container>
<unittitle>Negatives</unittitle>
</did>
</c04>
</c03>
提前感谢您的帮助!
推荐答案
试试下面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"></xsl:output>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c03/did">
<xsl:choose>
<xsl:when test="not(container)">
<did>
<!-- If no c03 container item is found, look in the c04 level for one -->
<xsl:if test="../c04/did/container">
<xsl:variable name="foo" select="../c04/did/container[@type='Box']/text()"/>
<!-- If a c04 container item is found, use the info to build a c03 version -->
<!-- Skip c03 container item, if still no c04 items found -->
<container label="Box" type="Box">
<!-- Build container list -->
<!-- Test for more than one item, and if so, list them, -->
<!-- separated by commas and a space -->
<xsl:for-each select="distinct-values($foo)">
<xsl:sort />
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="." />
</xsl:for-each>
</container>
<xsl:apply-templates select="*" />
</xsl:if>
</did>
</xsl:when>
<!-- If there is a c03 container item(s), list it normally -->
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
它看起来很像你想要的输出:
It looks pretty much as the output you want:
<?xml version="1.0" encoding="UTF-8"?>
<c03 id="ref6488" level="file">
<did>
<container label="Box" type="Box">154, 156</container>
<unittitle>Clinic Building</unittitle>
<unitdate era="ce" calendar="gregorian">1947</unitdate>
</did>
<c04 id="ref34582" level="file">
<did>
<container label="Box" type="Box">156</container>
<container label="Folder" type="Folder">3</container>
</did>
</c04>
<c04 id="ref6540" level="file">
<did>
<container label="Box" type="Box">156</container>
<unittitle>Contact prints</unittitle>
</did>
</c04>
<c04 id="ref6606" level="file">
<did>
<container label="Box" type="Box">154</container>
<unittitle>Negatives</unittitle>
</did>
</c04>
</c03>
诀窍是将 <xsl:sort>
和 distinct-values()
一起使用.请参阅 Michael Key 的(恕我直言)好书XSLT 2.0 and XPATH 2.0"
The trick is to use <xsl:sort>
and distinct-values()
together. See the (IMHO) great book from Michael Key "XSLT 2.0 and XPATH 2.0"
这篇关于如何在 XSL 中防止重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!