根据特定属性值更新XML属性

时间:2013-10-22 11:40:21

标签: xml xslt

在我的源XML中,我将所有实例ID从数字1重新分配到(直到存在)。我正在使用Profile元素下的上述值更新Apple,Mango,Banana InstanceId。在这里,我忽略了Profile InstanceID级别的出现。我的要求是仅当给定的“Profile”集合中的至少一个实例id大于25时触发这些xslt代码。

<Root>
  <Properties>
    <Props></Props>
    <Input></Input>
    <Profile InstanceID="4" ObjectID="XYZ">
      <foo>Profile 1</foo><!-- Need to update these set as atleast one instanceID is greater than 25 -->
      <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">
      <foo>Profile 1</foo><!-- no need to update these set as no instanceID is greater than 25 -->
      <Apple InstanceID="21" ObjectID="MNO" Type="103"></Apple>
      <Mango InstanceID="21" ObjectID="PQR" Type="103"></Mango>
      <Mango InstanceID="23" ObjectID="EFG" Type="103"></Mango>
      <Mango InstanceID="24" ObjectID="EFG123" Type="103"></Mango>
      <Banana InstanceID="25" ObjectID="GHI1" Type="103"></Banana>
    </Profile>
  </Properties>
</Root>

以下是我使用的XSLT

# 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>
  <xsl:template match="Profile/*/@InstanceID">
    <xsl:attribute name="InstanceID">
      <xsl:value-of select="count(../preceding-sibling::*[@InstanceID]) + 1" />
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

这些是输出/转换XML

# Transformed 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>
      <Mango InstanceID="2" ObjectID="DEF" Type="103"></Mango>
      <Mango InstanceID="3" ObjectID="GHI" Type="103"></Mango>
      <Banana InstanceID="4" 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="1" ObjectID="MNO" Type="103"></Apple>
      <Mango InstanceID="2" ObjectID="PQR" Type="103"></Mango>
      <Mango InstanceID="3" ObjectID="EFG" Type="103"></Mango>
      <Mango InstanceID="4" ObjectID="EFG123" Type="103"></Mango>
      <Banana InstanceID="5" ObjectID="GHI1" Type="103"></Banana>
    </Profile>
  </Properties>
</Root>

1 个答案:

答案 0 :(得分:0)

  

我的要求是仅当给定的“Profile”集合中的至少一个实例id大于25时触发这些xslt代码

您只需要使Profile/*/@InstanceID模板更具体一些。目前,它适用于所有 InstanceID元素的子元素的Profile属性,您需要在Profile级别添加谓词以将其限制为某些仅限个人资料:

<xsl:template match="Profile[*/@InstanceID &gt; 25]/*/@InstanceID">

这是因为如果集合中的任何节点满足所需条件,则一边是节点集的比较运算符为true,因此在这种情况下,如果 any InstanceID大于25。