Xslt XSL删除重复记录,考虑标记和值
考虑到标记/值,我想删除重复记录 以下是输入:Xslt XSL删除重复记录,考虑标记和值,xslt,duplicates,Xslt,Duplicates,考虑到标记/值,我想删除重复记录 以下是输入: <Details> <block order="1" title="Circle A" id="Circle"> <block id="square" title="Square 1" order="1"> <block id="d
<Details>
<block order="1" title="Circle A" id="Circle">
<block id="square" title="Square 1" order="1">
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">Sun</field>
<field order="4" title="D" id="ID d">45-34-YT</field>
<field order="5" title="E" id="ID e">500</field>
<field order="6" title="F" id="ID f">ABC</field>
<field order="7" title="G" id="ID g">Street xpto</field>
<field order="8" title="H" id="ID h">39RT</field>
<field order="9" title="I" id="ID i">Working Closet</field>
</block>
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">Sun</field>
<field order="4" title="D" id="ID d">45-34-YT</field>
<field order="5" title="E" id="ID e">500</field>
<field order="6" title="F" id="ID f">ABC</field>
<field order="7" title="G" id="ID g">Street xpto</field>
<field order="8" title="H" id="ID h">39RT</field>
<field order="9" title="I" id="ID i">Working Closet</field>
</block>
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">Sun</field>
<field order="4" title="D" id="ID d">45-34-YT</field>
<field order="5" title="E" id="ID e">500</field>
<field order="6" title="F" id="ID f">ABC</field>
<field order="7" title="G" id="ID g">Street xpto</field>
<field order="8" title="H" id="ID h">39RT</field>
<field order="9" title="I" id="ID i">Working Closet</field>
</block>
</block>
</block>
</Details>
500
街道xpto
太阳
45-34-YT
500
基础知识
街道xpto
39RT
工作间
500
街道xpto
太阳
45-34-YT
500
基础知识
街道xpto
39RT
工作间
500
街道xpto
太阳
45-34-YT
500
基础知识
街道xpto
39RT
工作间
以下是期望输出:
<Details>
<block order="1" title="Circle A" id="Circle">
<block id="square" title="Square 1" order="1">
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">Sun</field>
<field order="4" title="D" id="ID d">45-34-YT</field>
<field order="5" title="E" id="ID e">500</field>
<field order="6" title="F" id="ID f">ABC</field>
<field order="7" title="G" id="ID g">Street xpto</field>
<field order="8" title="H" id="ID h">39RT</field>
<field order="9" title="I" id="ID i">Working Closet</field>
</block>
</block>
</block>
</Details>
500
街道xpto
太阳
45-34-YT
500
基础知识
街道xpto
39RT
工作间
我已尝试使用此xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:if test="not(preceding-sibling::node()[.=string(current())])">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
但我需要删除这些行:
<field order="5" title="E" id="ID e">500</field>
<field order="7" title="G" id="ID g">Street xpto</field>
500
街道xpto
因为我的xslt只考虑标记值。
我不知道如何考虑全行而不是只考虑价值。
有人能帮忙吗
谢谢。
何塞
更精确的样品。
例1:
输入:
500
街道xpto
500
500
街道xpto
500
500
街道xpto
500
输出:
<Details>
<block order="1" title="Circle A" id="Circle">
<block id="square" title="Square 1" order="1">
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">500</field>
</block>
</block>
</block>
</Details>
<Details>
<block order="1" title="Circle A" id="Circle">
<block id="square" title="Square 1" order="1">
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">Sun</field>
</block>
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street A</field>
<field order="3" title="C" id="ID c">Sun</field>
</block>
</block>
</block>
</Details>
500
街道xpto
500
结果:一个不同的块id“点”
例2:
第三个街区不同,因为第二个街区现在是“街道A”
输入:
500
街道xpto
500
500
街道xpto
500
500
A街
500
输出:
<Details>
<block order="1" title="Circle A" id="Circle">
<block id="square" title="Square 1" order="1">
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">500</field>
</block>
</block>
</block>
</Details>
<Details>
<block order="1" title="Circle A" id="Circle">
<block id="square" title="Square 1" order="1">
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street xpto</field>
<field order="3" title="C" id="ID c">Sun</field>
</block>
<block id="dot" title="test" order="1">
<field order="1" title="A" id="ID a">500</field>
<field order="2" title="B" id="ID b">Street A</field>
<field order="3" title="C" id="ID c">Sun</field>
</block>
</block>
</block>
</Details>
500
街道xpto
太阳
500
A街
太阳
结果:两个不同的块id为“点”
我希望这些新的样本有助于澄清我的伪装。
提前感谢您的回复和回答。在XSLT 2或3中,您的需求可以用
deep equal
表达(当然还有身份转换):
我希望XSLT3的唯一用途是
,它应该被模板所取代
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
对于XSLT 1,我希望下面使用两个键就足够了:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="block" match="block[@id = 'dot']" use="concat(@title, '|', @order)"/>
<xsl:key name="field" match="block[@id = 'dot']/field" use="concat(../@title, '|', ../@order, '|', @order, '|', @title, '|', @id, '|', .)"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="block[@id = 'dot'][not(generate-id() = generate-id(key('block', concat(@title, '|', @order))[1]))][not(field[generate-id() = generate-id(key('field', concat(../@title, '|', ../@order, '|', @order, '|', @title, '|', @id, '|', .))[1])])]"/>
</xsl:stylesheet>
但我还没有完全测试过,我不确定这种方法是否遗漏了一些方面,比如子元素的顺序。这可能是您需要的吗? 它使用块[field]的@id来查看它是否是唯一具有该@id的块[field]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="block[field]">
<xsl:variable name="id" select="@id"/>
<xsl:if test="not( preceding-sibling::block[@id=$id])">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
2021年4月10日:在OP发布了更多的例子之后,我认为这应该能起到作用:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="block[block[field]]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="block[1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="block[field]">
<xsl:variable name="fields" select="normalize-space(.)"/>
<xsl:if test="not(following-sibling::block[normalize-space(.)=$fields])">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="field"/>
</xsl:copy>
</xsl:if>
<xsl:apply-templates select="following-sibling::block[1]"/>
</xsl:template>
</xsl:stylesheet>
块之间的字段是否可能有任何不同?如果是这样的话,你能举个例子吗?如果你局限于XSLT1.0,那么就用XSLT1.0来代替现在效率低下的方法。这也将允许你使用一个键来连接所有你想考虑的值(哪些是你的问题不清楚的)。differ@michael.hor257k,我希望始终拥有唯一的@JoseMartins,您使用或可以使用哪个XSLT处理器,哪个版本?唯一内容的确切含义是什么?XPath2和更高版本的函数deep equal
是否表达了这一要求?谢谢。快到了。但是这个解决方案不考虑字段标签值的变化,请检查我提出的新的样本。@何塞·马丁斯:请再试一次这个更新版本XSLT版本1。谢谢,但这不起作用。@ JojeMARTIN,对于哪个样本它不起作用?并且似乎给出了你想要的结果。它起作用了,我错误地复制了你的解决方案。谢谢。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="block[field]">
<xsl:variable name="id" select="@id"/>
<xsl:if test="not( preceding-sibling::block[@id=$id])">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="block[block[field]]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="block[1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="block[field]">
<xsl:variable name="fields" select="normalize-space(.)"/>
<xsl:if test="not(following-sibling::block[normalize-space(.)=$fields])">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="field"/>
</xsl:copy>
</xsl:if>
<xsl:apply-templates select="following-sibling::block[1]"/>
</xsl:template>
</xsl:stylesheet>