0

次の 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 は変更されません。ノード ナビゲーションに習熟していないため、希望どおりの結果が得られません。変換を手伝ってくれる人はいますか? 前もって感謝します。

  • ローレンツ
4

1 に答える 1

1

この単純な 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. その目的は、すべてのノードと属性をソース ドキュメントから結果ドキュメントにそのままコピーすることです。
  • 1 つのテンプレートが ID テンプレートをオーバーライドします。その目的は、元の開始ビットを正しい@Size属性 (現在の要素に先行するもの) に追加することです。これにより、後続の各要素の属性<Fields>の値が形成されます。<Fields>@StartingBit
于 2012-10-26T22:54:22.593 に答える