我是XSLT的新手。 我试图将XML的当前int更新为大于25的XML到1-25范围内的唯一ID。
*的 MYXML *
<Root>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile InstanceID ="4" ObjectID="XYZ"> (no need to update these instanceID)
<ELM_INT>Profile 1</ELM_INT>
<Video **InstanceID="26"** ObjectID="ABC" Type="103"></Video>
<Audio **InstanceID="1"** ObjectID="DEF" Type="103"></Audio>
<Audio **InstanceID="27"** ObjectID="GHI" Type="103"></Audio>
<Output ObjectID="JKL" Type="104" Type="25"></Output>
</Profile>
</Properties>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile InstanceID ="4" ObjectID="XYZ"> (no need to update these instanceID)
<ELM_INT>Profile 1</ELM_INT>
<Video **InstanceID="33"** ObjectID="MNO" Type="103"></Video>
<Audio **InstanceID="25"** ObjectID="PQR" Type="103"></Audio>
<Audio **InstanceID="2"** ObjectID="EFG" Type="103"></Audio>
<Output ObjectID="HIJ" Type="104" Type="25"></Output>
</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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!--Main START-->
<xsl:template name="Main" match="Profile/*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
<!--Get all instance id's includng Profile and call loop-->
<xsl:for-each select="@*/..">
<!--Id instanceId is greater than 25 than call loop-->
<xsl:variable name="CurrentInstanceID">
<xsl:value-of select="@InstanceID"/>
</xsl:variable>
<xsl:if test="$CurrentInstanceID > 25">
<!--<xsl:text> .Calling Iterate1To25 </xsl:text>-->
<xsl:call-template name="Iterate1To25">
<xsl:with-param name="pStart" select="1"/>
<xsl:with-param name="pEnd" select="25"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!--Main END-->
<!-- Iterate1To25which iterate for 25 times START-->
<xsl:template name="Iterate1To25" >
<xsl:param name="pStart"/>
<xsl:param name="pEnd"/>
<xsl:if test="not($pStart > $pEnd)">
<xsl:variable name="serchAudeoInstanceID">
<xsl:value-of select="count(../Audio[@InstanceID=$pStart])"/>
</xsl:variable>
<xsl:variable name="serchVideoInstanceID">
<xsl:value-of select="count(../Video[@InstanceID=$pStart])"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$serchAudeoInstanceID > 0 or $serchVideoInstanceID > 0>
<xsl:call-template name="Iterate1To25">
<xsl:with-param name="pStart" select="$pStart+1"/>
<xsl:with-param name="pEnd" select="25"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!--pStart can be assigned-->
<xsl:element name="Valid_ID">
<xsl:value-of select="$pStart"/>
<xsl:attribute name="InstanceID">
<xsl:value-of select="$pStart"/>
</xsl:attribute>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出/转换XML
<Root>
<Properties>
<Props></Props>
<Input>
</Input>
<Profile_InstanceID ="4" ObjectID="XYZ">
<ELM_INT>Profile 1</ELM_INT>
<Video **InstanceID="26"** ObjectID="ABC" Type="103"></Video>
****<ValidID>2</ValidID>****
<Audio **InstanceID="1"** ObjectID="DEF" Type="103"></Audio>
<Audio **InstanceID="27"** ObjectID="GHI" Type="103"></Audio>
****<ValidID>2</ValidID> (expected 3)****
<Output ObjectID="JKL" Type="104" Type="25"></Output>
</Profile_Instance>
</Properties>
<Properties>
<Props></Props>
<InputTransport>
</InputTransport>
<Profile_InstanceID ="4" ObjectID="XYZ">
<ELM_INT>Profile 1</ELM_INT>
<Video **InstanceID="33"** ObjectID="MNO" Type="103"></Video>
****<ValidID>1</ValidID>****
<Audio **InstanceID="25"** ObjectID="PQR" Type="103"></Audio>
<Audio **InstanceID="2"** ObjectID="EFG" Type="103"></Audio>
<Output ObjectID="HIJ" Type="104" Type="25"></Output>
</Profile_Instance>
</Properties>
</Root>
查询 1.如何更新属性InstanceID而不是附加其他元素 2.如何跟踪生成/分配/新生成的实例Id,以避免重复。
提前致谢,任何帮助都会很明显。
答案 0 :(得分:1)
您已经使用身份模板开始了正确的方式,但后来我不明白您下一步要做什么。你有这个:
match="Profile/*"
但我在源文档中看不到任何名为Profile
的元素。我期望从您对问题的描述中看到的是这样的:
<xsl:template match="@InstanceID[. > 25]">
<xsl:attribute name="InstanceId" select="xxxx"/>
</xsl:template>
其中xxxx是属性的新值;这就是问题的下一部分。这不是特别容易,但你似乎有计算变量$ pstart的所有逻辑,这似乎是你想要的值,所以只需将其用作上面的xxxxx。
答案 1 :(得分:0)
让我们尝试解决分配唯一ID的问题。这个很难,很高兴知道真正的要求是什么,因为它可能过度约束。
我认为,我会首先使用初始传递来确定正在使用的标识符,并生成包含可供使用的标识符的XML文档。这并不太难:基本上(在伪代码中)“对于我在1到N的地方没有(我在输入中出现)返回i”。
然后我将构建一个需要更改标识符的节点列表,将此列表放在一个变量中;然后使用此变量作为参数进行文档的树形遍历;当列表中存在节点时,作为列表中的第N个项目,将标识符替换为“免费使用”列表中第N个标识符的id。
我不会尝试使用XSLT 1.0。但是,我不会尝试使用XSLT 1.0;一旦你习惯了2.0,那就太辛苦了。另外,请不要让我将此算法转换为XSLT代码;如果你不能自己做,你应该付钱给别人为你做。