我的源xml具有相同标记名称的不同节点。我想将这个xml转换为xml,其中每个子节点都是唯一的,例如:这是我的xml:
<?xml version="1.0" encoding="utf-16"?>
<shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" orderid="orderid1">
<orderperson>orderperson1</orderperson>
<shipto>
<name>name1</name>
<address>address1</address>
<city>city1</city>
<country>country1</country>
</shipto>
<item>
<title>title1</title>
<note>note1</note>
<note>1</note>
</item>
<item>
<title>title2</title>
<note>note2</note>
</item>
</shiporder>
转换后的结果应如下所示:
<?xml version="1.0" encoding="utf-16"?>
<shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" orderid="orderid1">
<orderperson>orderperson1</orderperson>
<shipto>
<name>name1</name>
<address>address1</address>
<city>city1</city>
<country>country1</country>
</shipto>
<item>
<title>title1</title>
<note>note1</note>
</item>
</shiporder>
我试图通过*[1]
选择第一个孩子,如果有一个标签名称相同但是到目前为止我没有得到正确的结果:
<xsl:template match="/">
<xsl:copy-of select="//*[1]"/>
</xsl:template>
答案 0 :(得分:1)
使用XSLT 2.0,您可以尝试
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:key name="name" match="*" use="node-name(.)"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(. is key('name', node-name(.), ..)[1])]"/>
</xsl:stylesheet>
应该对您显示的样本执行此操作。另一方面,如果可以嵌套相同名称的元素,则需要使用不同的模式:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[preceding-sibling::*[node-name(.) eq node-name(current())]]"/>
</xsl:stylesheet>