繁体   English   中英

XSLT v1.0根据先前节点的属性更新节点集中的属性

[英]XSLT v1.0 Updating attribute in node-set based on previous node's attribute

我有以下XML文件。

<Record 
  Name="My_Record"
  <Fields
    StartingBit="0"
    Size="3"
    Name="Field_1">
  </Fields>
  <Fields 
    StartingBit="1"
    Size="5"
    Name="Field_2">
  </Fields>
  <Fields
    StartingBit="2"
    Size="8"
    Name="Field_3">
  </Fields>
  <Fields
    StartingBit="3"
    Size="4"
    Name="Field_4"
  </Fields>
</Record>

我想使用XSLT从先前节点的@StartingBit + @Size正确更新@StartingBit属性-这将是当前节点的@StartingBit值。 生成的XML应该如下所示:

<Record 
  Name="My_Record"
  <Fields
    StartingBit="0"
    Size="3"
    Name="Field_1">
  </Fields>
  <Fields 
    StartingBit="3"
    Size="5"
    Name="Field_2">
  </Fields>
  <Fields
    StartingBit="8"
    Size="8"
    Name="Field_3">
  </Fields>
  <Fields
    StartingBit="16"
    Size="4"
    Name="Field_4"
  </Fields>
</Record>

到目前为止,我对XSLT的最新尝试如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match ="Fields/@StartingBit">
    <xsl:value-of select ="(preceding-sibling::Fields[1]/@StartingBit + preceding-sibling::Fields[1]/@Size)"/>
  </xsl:template>
</xsl:stylesheet>

上面的转换不会生成我想要的内容-基本上@StartingBit不会更改。 我不擅长节点导航来获得所需的结果-有人可以协助我进行转换吗? 先感谢您。

  • 洛伦兹

当这个简单的XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:variable name="vStartingBit" select="/*/Fields[1]/@StartingBit" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Fields[position() &gt; 1]">
    <xsl:copy>
      <xsl:attribute name="StartingBit">
        <xsl:value-of
          select="$vStartingBit + sum(preceding-sibling::Fields/@Size)" />
      </xsl:attribute>
      <xsl:apply-templates select="@*[not(name() = 'StartingBit')]" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

...应用于原始XML(已更正,格式正确):

<?xml version="1.0" encoding="utf-8"?>
<Record Name="My_Record">
  <Fields StartingBit="0" Size="3" Name="Field_1" />
  <Fields StartingBit="1" Size="5" Name="Field_2" />
  <Fields StartingBit="2" Size="8" Name="Field_3" />
  <Fields StartingBit="3" Size="4" Name="Field_4" />
</Record>

...产生了预期的结果:

<?xml version="1.0"?>
<Record Name="My_Record">
  <Fields StartingBit="0" Size="3" Name="Field_1" />
  <Fields StartingBit="3" Size="5" Name="Field_2" />
  <Fields StartingBit="8" Size="8" Name="Field_3" />
  <Fields StartingBit="16" Size="4" Name="Field_4" />
</Record>

说明:

  • 第一个模板是Identity Template 其目的是将所有节点和属性从源文档原样复制到结果文档。
  • 一个模板将覆盖身份模板。 目的是将原始起始位添加到正确的@Size属性(当前<Fields>元素之前的那些),该属性形成每个后续<Fields>元素的@StartingBit属性的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM