我有这个XML:-
<?xml version="1.0" encoding="UTF-8"?>
<queryResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<records xsi:type="sObject">
<type>Task</type>
<id>1</id>
<name>1xyz</name>
<lastname>1abc </lastname>
<id>1</id>
</records>
<records xsi:type="sObject">
<type>Task</type>
<id>2</id>
<name>2xyz</name>
<lastname>2abc </lastname>
<id>2</id>
</records>
</queryResult>
我想删除同一记录字段中的第二个id标签。所以我想要的xml是:-
<?xml version="1.0" encoding="UTF-8"?>
<queryResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<records xsi:type="sObject">
<type>Task</type>
<id>1</id>
<name>1xyz</name>
<lastname>1abc </lastname>
</records>
<records xsi:type="sObject">
<type>Task</type>
<id>2</id>
<name>2xyz</name>
<lastname>2abc </lastname>
</records>
</queryResult>
所以基本上我想从我的xml中删除该多余的id标记。
答案 0 :(得分:3)
由于您未指定XSLT版本,因此我使用的是2.0版。
请注意,您的源XML使用的默认命名空间
http://www.force.com/2009/06/asyncapi/dataload ,因此通常您应该
在stylesheet
XSLT元素中提及它。
但是为了简化脚本,您可以将其指定为xpath-default-namespace
,
因此您无需将其指定为“常规”命名空间。
编写脚本的想法很简单:编写与records
相匹配的模板
(在默认名称空间中,如之前指定的)。该模板应:
id
子元素。id
之外的所有子元素。您的脚本还应该包括身份模板。
因此整个脚本可以如下:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.force.com/2009/06/asyncapi/dataload">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="records">
<xsl:copy>
<xsl:apply-templates select="id[1]"/>
<xsl:apply-templates select="* except id"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
有关工作示例,请参见http://xsltransform.net/pNvs5wD
另一种解决方案是编写与id
匹配的空模板,
其中的preceding-sibling
元素名为id
:
<xsl:template match="id[preceding-sibling::id]"/>
因此整个脚本可以是:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.force.com/2009/06/asyncapi/dataload">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="id[preceding-sibling::id]"/>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
区别在于,这次您保持子元素的顺序,
而第一个解决方案将id
元素“移动”到开头。
注意:这次我添加了<xsl:strip-space elements="*"/>
以避免为空
输出中的行。