删除 XSLT 中重复的 XML 个节点
Removing duplicate XML nodes in XSLT
如果有人可以帮助我创建 xslt 以从 XML 中删除重复节点,我将不胜感激
基于重复元素的值 (PlayBack--ControlInfo-ControlName)。
我想从 GStep/Step
中删除所有重复元素(PlayBack--ControlInfo-ControlName)
输入XML
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Meta>
<GpsFile>notepad_may_30_file</GpsFile>
<GpsId>36fa4fe8-9691-4a7f-8bc1-9543f6b7d29a</GpsId>
<ExePath>
<ExePath1>C:\WINDOWS\SYSTEM32\notepad.exe</ExePath1>
</ExePath>
</Meta>
<Process>
<GStep DialogName="Untitled - Notepad">
<Step DialogName="Untitled - Notepad">
<Step-ID>3</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>4</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>5</Step-ID>
<PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>6</Step-ID>
<PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>12</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>13</Step-ID>
<PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>14</Step-ID>
<PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>15</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
</GStep>
<GStep DialogName="Replace">
<Step DialogName="Replace">
<Step-ID>8</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Replace">
<Step-ID>9</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Replace">
<Step-ID>10</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Replace">
<Step-ID>16</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
</GStep>
</Process>
</Document>
实际上期待如下结果。
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Meta>
<GpsFile>notepad_may_30_file</GpsFile>
<GpsId>36fa4fe8-9691-4a7f-8bc1-9543f6b7d29a</GpsId>
<ExePath>
<ExePath1>C:\WINDOWS\SYSTEM32\notepad.exe</ExePath1>
</ExePath>
</Meta>
<Process>
<GStep DialogName="Untitled - Notepad">
<Step DialogName="Untitled - Notepad">
<Step-ID>3</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>5</Step-ID>
<PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>6</Step-ID>
<PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-
ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>15</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
</GStep>
<GStep DialogName="Replace">
<Step DialogName="Replace">
<Step-ID>8</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Replace">
<Step-ID>9</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
</GStep>
</Process>
</Document>
我尝试使用以下 xslt 代码片段。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="ControlNameInfo" match="Step" use="PlayBack--ControlInfo-ControlName"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GStep/Step[not(generate-id() = generate-id(key('ControlNameInfo', PlayBack--
ControlInfo-ControlName)[1]))]"/>
</xsl:stylesheet>
Can anyone help
Thanks very much.
为了在每个 GStep
中仅保留不同的 Step
节点,您必须在密钥中包含父节点 GStep
。尝试:
XSLT 1.0
<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:strip-space elements="*"/>
<xsl:key name="k1" match="Step" use="concat(PlayBack--ControlInfo-ControlName, '|', generate-id(..))"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GStep">
<xsl:copy>
<xsl:apply-templates select="Step[generate-id()=generate-id(key('k1', concat(PlayBack--ControlInfo-ControlName, '|', generate-id(..)))[1])]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您还可以在 XSLT 2.0 中使用 group-by 方法。
XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove duplicates -->
<xsl:template match="GStep">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="Step" group-by="PlayBack--ControlInfo-ControlName">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果有人可以帮助我创建 xslt 以从 XML 中删除重复节点,我将不胜感激 基于重复元素的值 (PlayBack--ControlInfo-ControlName)。
我想从 GStep/Step
中删除所有重复元素(PlayBack--ControlInfo-ControlName)输入XML
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Meta>
<GpsFile>notepad_may_30_file</GpsFile>
<GpsId>36fa4fe8-9691-4a7f-8bc1-9543f6b7d29a</GpsId>
<ExePath>
<ExePath1>C:\WINDOWS\SYSTEM32\notepad.exe</ExePath1>
</ExePath>
</Meta>
<Process>
<GStep DialogName="Untitled - Notepad">
<Step DialogName="Untitled - Notepad">
<Step-ID>3</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>4</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>5</Step-ID>
<PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>6</Step-ID>
<PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>12</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>13</Step-ID>
<PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>14</Step-ID>
<PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>15</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
</GStep>
<GStep DialogName="Replace">
<Step DialogName="Replace">
<Step-ID>8</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Replace">
<Step-ID>9</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Replace">
<Step-ID>10</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Replace">
<Step-ID>16</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
</GStep>
</Process>
</Document>
实际上期待如下结果。
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Meta>
<GpsFile>notepad_may_30_file</GpsFile>
<GpsId>36fa4fe8-9691-4a7f-8bc1-9543f6b7d29a</GpsId>
<ExePath>
<ExePath1>C:\WINDOWS\SYSTEM32\notepad.exe</ExePath1>
</ExePath>
</Meta>
<Process>
<GStep DialogName="Untitled - Notepad">
<Step DialogName="Untitled - Notepad">
<Step-ID>3</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>5</Step-ID>
<PlayBack--ControlInfo-ControlName>Edit</PlayBack--ControlInfo-ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>6</Step-ID>
<PlayBack--ControlInfo-ControlName>Replace...\tCtrl+H</PlayBack--ControlInfo-
ControlName>
</Step>
<Step DialogName="Untitled - Notepad">
<Step-ID>15</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
</GStep>
<GStep DialogName="Replace">
<Step DialogName="Replace">
<Step-ID>8</Step-ID>
<PlayBack--ControlInfo-ControlName />
</Step>
<Step DialogName="Replace">
<Step-ID>9</Step-ID>
<PlayBack--ControlInfo-ControlName>Cancel</PlayBack--ControlInfo-ControlName>
</Step>
</GStep>
</Process>
</Document>
我尝试使用以下 xslt 代码片段。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="ControlNameInfo" match="Step" use="PlayBack--ControlInfo-ControlName"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GStep/Step[not(generate-id() = generate-id(key('ControlNameInfo', PlayBack--
ControlInfo-ControlName)[1]))]"/>
</xsl:stylesheet>
Can anyone help
Thanks very much.
为了在每个 GStep
中仅保留不同的 Step
节点,您必须在密钥中包含父节点 GStep
。尝试:
XSLT 1.0
<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:strip-space elements="*"/>
<xsl:key name="k1" match="Step" use="concat(PlayBack--ControlInfo-ControlName, '|', generate-id(..))"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GStep">
<xsl:copy>
<xsl:apply-templates select="Step[generate-id()=generate-id(key('k1', concat(PlayBack--ControlInfo-ControlName, '|', generate-id(..)))[1])]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您还可以在 XSLT 2.0 中使用 group-by 方法。
XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove duplicates -->
<xsl:template match="GStep">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="Step" group-by="PlayBack--ControlInfo-ControlName">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>