在我的 Souce XML 中,我想重新分配从数字 1 开始的所有实例 ID(直到存在)。
我想在 Profile 元素下使用上述值更新 Apple、Mango、Banana InstanceId。
在这里,我将忽略配置文件 InstanceID
级别的出现。
由于我是 XSLT 的新手,所以任何要点都会很明显。
在下面的示例中,我使用了 XSLT ,但它将所有出现的情况替换为 1。
<Root>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile InstanceID ="4" ObjectID="XYZ"> <!-- no need to update these instanceID -->
<foo>Profile 1</foo>
<Apple InstanceID="26" ObjectID="ABC" Type="103"></Apple>
<Mango InstanceID="1" ObjectID="DEF" Type="103"></Mango>
<Mango InstanceID="27" ObjectID="GHI" Type="103"></Mango>
<Banana InstanceID="29" ObjectID="GHI1" Type="103"></Banana>
</Profile>
</Properties>
<Properties>
<Props></Props>
<Input></Input>
<Profile InstanceID ="4" ObjectID="XYZ"> <!-- no need to update these instanceID -->
<foo>Profile 1</foo>
<Apple InstanceID="33" ObjectID="MNO" Type="103"></Apple>
<Mango InstanceID="25" ObjectID="PQR" Type="103"></Mango>
<Mango InstanceID="2" ObjectID="EFG" Type="103"></Mango>
<Mango InstanceID="28" ObjectID="EFG123" Type="103"></Mango>
<Banana InstanceID="31" ObjectID="GHI1" Type="103"></Banana>
</Profile>
</Properties>
</Root>
下面是我使用的 XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:variable name="counter1" select="0"></xsl:variable>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Profile/*/@InstanceID">
<xsl:attribute name="InstanceID">
<xsl:value-of select="position()" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
这些是输出/转换后的 XML
<Root>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile InstanceID ="4" ObjectID="XYZ"> <!-- no need to update these instanceID -->
<foo>Profile 1</foo>
<Apple InstanceID="1" ObjectID="ABC" Type="103"></Apple> <!-- Correct -->
<Mango InstanceID="1" ObjectID="DEF" Type="103"></Mango> <!-- Expected val = 2 -->
<Mango InstanceID="1" ObjectID="GHI" Type="103"></Mango> <!-- Expected val = 3 -->
<Banana InstanceID="1" ObjectID="GHI1" Type="103"></Banana> <!-- Expected val = 4 -->
</Profile>
</Properties>
<Properties>
<Props></Props>
<Input></Input>
<Profile InstanceID ="4" ObjectID="XYZ"> <!-- no need to update these instanceID -->
<foo>Profile 1</foo>
<Apple InstanceID="1" ObjectID="MNO" Type="103"></Apple> <!-- Correct -->
<Mango InstanceID="1" ObjectID="PQR" Type="103"></Mango> <!-- Expected val = 2 -->
<Mango InstanceID="1" ObjectID="EFG" Type="103"></Mango> <!-- Expected val = 3 -->
<Mango InstanceID="1" ObjectID="EFG123" Type="103"></Mango> <!-- Expected val = 4 -->
<Banana InstanceID="1" ObjectID="GHI1" Type="103"></Banana> <!-- Expected val = 5 -->
</Profile>
</Properties>
</Root>
最佳答案
问题出在
<xsl:value-of select="position()" />
该行不显示水果元素的 position()
,而是显示属性 @InstanceID
的位置(自然地,始终为 1)。
要解决此问题,您不得使用 position()
,而是计算包含 @InstanceID
属性的父级的所有先前同级:
<xsl:value-of select="count(../preceding-sibling::*[@InstanceID]) + 1" />
关于xml - 更新 XSLT For 循环中的 XML 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19464207/