0

次のXMLドキュメントがあります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Entity Type="defect">
  <Fields>
    <Field Name="user-28"/>
    <Field Name="user-29">
      <Value>1</Value>
    </Field>
    <Field Name="has-change">
      <Value></Value>
    </Field>
    ...

これを変換して、すべてのField要素が要素にName変換された属性を持つ要素になり、要素を削除するようにしようとしていFieldsます。これまでのところ、次の変換を使用して部分的に成功しています。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8"
              indent="yes"/>
  <xsl:template match="//Entity">
    <xsl:copy>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="Field">
    <xsl:element name="{@Name}">
      <xsl:value-of select="Value"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

その結果、次のようになります。これは部分的には正しいですが、要素のType属性が失われます。Entity

<?xml version="1.0" encoding="UTF-8"?>
<Entity>

    <user-28/>
    <user-29>1</user-29>
    <has-change/>

さらに厄介なのは、ルートノードを失うことなくEntities複数のノードを持つルートノードを含む次のドキュメントでもこれを機能させる必要があることです。Entity

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Entities TotalResults="60">
  <Entity Type="defect">
    <Fields>
      <Field Name="id">
        <Value>1161</Value>
      </Field>
4

2 に答える 2

1

<xsl:copy>ノード自体のみをコピーし、その属性または子ノードの場合はコピーしません。属性に適用され、完全な属性、つまり名前と値をコピーします。

ドキュメントの大部分を保持する変換を行う場合は、ID変換テンプレートを使用することをお勧めします。これはどうですか:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8"
    indent="yes"/>

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

  <!-- We don't want to copy <Fields>, just the contents -->
  <xsl:template match="Fields">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="Field">
    <xsl:element name="{@Name}">
      <xsl:value-of select="Value"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>
于 2012-11-16T08:20:57.440 に答える
1

あなたはとても近いです。以下の私の答えのわずかな変更をご覧ください。

このXSLT1.0ソリューションの場合:

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

  <xsl:template match="Fields">
     <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="Field">
     <xsl:element name="{@Name}">
       <xsl:value-of select="Value" />
     </xsl:element>
  </xsl:template>

</xsl:stylesheet>

...最初に提供されたXMLに対して適用されます:

<?xml version="1.0" encoding="UTF-8"?>
<Entity Type="defect">
  <Fields>
    <Field Name="user-28"/>
    <Field Name="user-29">
      <Value>1</Value>
    </Field>
    <Field Name="has-change">
      <Value/>
    </Field>
    <!-- other <Field> elements -->
  </Fields>
</Entity>

...必要な結果が生成されます:

<?xml version="1.0"?>
<Entity Type="defect">
  <user-28 />
  <user-29>1</user-29>
  <has-change />
  <!-- other <Field> elements -->
</Entity>

これと同じXSLTが2番目に提供されたXMLに対して実行される場合:

<?xml version="1.0" encoding="UTF-8"?>
<Entities TotalResults="60">
  <Entity Type="defect">
    <Fields>
      <Field Name="id">
        <Value>1161</Value>
      </Field>
      <!-- other <Field> elements -->
    </Fields>
  </Entity>
</Entities>

...繰り返しますが、必要な結果が生成されます。

<?xml version="1.0"?>
<Entities TotalResults="60">
  <Entity Type="defect">
    <id>1161</id>
    <!-- other <Field> elements -->
  </Entity>
</Entities>

説明:

  • 最初のテンプレートはThe Identity Transformです。おそらく推測できるように、その目的は、デフォルトで、すべてのノードと属性をソースドキュメントから結果ドキュメントにそのままコピーすることです。
  • 2番目のテンプレートはすべての<Fields>要素に一致します。XSLTパーサーは、テンプレートを見つけると、その子要素にテンプレートを適用するように指示されます(さらに、その<Fields>要素を削除する効果があります)。
  • 最終的なテンプレートは、すでに持っているものと同じです。
于 2012-11-16T08:21:22.067 に答える