更新时间:2023-12-05 13:16:22
这可以通过 XSLT 轻松实现.首先,您将创建一个模板来匹配以 UPC
This can be achieved quite easily with XSLT. First of all you would create a template to match elements beginning with UPC
<xsl:template match="product/*[starts-with(local-name(), 'UPC')]">
然后您将根据元素的位置创建一个新元素,并使用修改后的名称
Then you would create a new element, with your revised name, based on the element's position
<xsl:element name="UPC_{position()}">
请注意此处在创建名称时使用了属性值模板".花括号表示这是一个要计算的表达式,而不是字面上的输出.
Note the use of "Attribute Value Templates" here in creating the name. The curly braces indicate this is an expression to be evaluated, not output literally.
这是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="product/*[starts-with(local-name(), 'UPC')]">
<xsl:element name="UPC_{position()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用您的 XML 后,输出如下
When applied your XML, the following is output
<products>
<product>
<UPC_1>123</UPC_1>
<UPC_2>223</UPC_2>
<UPC_3>345</UPC_3>
<other>unchange</other>
</product>
<product>
<UPC_1>1234</UPC_1>
<UPC_2>1235</UPC_2>
<other>unchange</other>
</product>
</products>
话虽如此,只有当您的 UPC 元素始终是第一个元素时,它才会起作用.如果你有这个作为输入
Having said that, it would only work if your UPC elements are always the first elements. If you had this as input
<product>
<UPC_US>123</UPC_US>
<UPC_UK>223</UPC_UK>
<UPC_JP>345</UPC_JP>
<other>unchange</other>
</product>
输出是这样的
<products>
<product>
<UPC_1>123</UPC_1>
<UPC_2>223</UPC_2>
<other>unchange</other>
<UPC_4>345</UPC_4>
</product>
</products>
如果这不是您想要的,您可以改为使用 xsl:number 来计算元素.试试这个 XSLT
If this is not what you want, you could instead make use of xsl:number to count the elements. Try this XSLT instead
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="product/*[starts-with(local-name(), 'UPC')]">
<xsl:variable name="count">
<xsl:number count="*[starts-with(local-name(), 'UPC')]"/>
</xsl:variable>
<xsl:element name="UPC_{$count}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在这种情况下,第二个例子会产生这个
In this case, the second example would yield this
<products>
<product>
<UPC_1>123</UPC_1>
<UPC_2>223</UPC_2>
<other>unchange</other>
<UPC_3>345</UPC_3>
</product>
</products>
在这两种情况下,请注意使用 Indentity Transform 模板按原样复制所有其他元素.
In both cases, make note of the use of the Indentity Transform template to copy all other elements as-is.