1

XSLT を使用して入力 xml から重複ノードを削除する際に助けが必要です

これは私のXMLがどのように見えるかです。

<?xml version="1.0"?>

<NodeA NodeAattr="123">

<NodeB NodeBattr="456"></NodeB>

<NodeC>
    <NodeD="ValueD">
       <NodeE Name="ValueABC">
          <NodeF Value="0"></NodeF >
       </NodeE >
       <NodeE Name="ValueABC">
          <NodeF Value="0"></NodeF >
       </NodeE>
  </NodeD>
</NodeC>
</NodeA>

私の最終的な出力は次のようになります

<NodeA NodeAattr="123">

<NodeB NodeBattr="456"></NodeB>

<NodeC>
    <NodeD="ValueD">
       <NodeE Name="ValueABC">
          <NodeF Value="0"></NodeF>
       </NodeE >
    </NodeD>
</NodeC>
</NodeA>

ここで、ノード E の Name 属性の値が重複しています。この属性に基づいて、重複を排除する必要があります。

ここで出力を取得するために必要な XSLT について、誰かが私を助けてくれると本当に助かります。XSLT 1.0 しか使えない

4

2 に答える 2

1

2 つの<NodeE>要素が同じ親を持つ場合にのみ重複と見なされる場合、これがおそらく最も簡単な解決策です。

入力

<?xml version="1.0"?>

<NodeA NodeAattr="123">

  <NodeB NodeBattr="456"></NodeB>

  <NodeC>
    <NodeD Name="ValueD">
      <NodeE Name="ValueABC">
        <NodeF Value="0"></NodeF>
      </NodeE>
      <NodeE Name="ValueABC">
        <NodeF Value="0"></NodeF>
      </NodeE>
    </NodeD>
    <!-- Added another <NodeD> element for demonstration -->
    <NodeD>
      <NodeE Name="ValueABC">
        <NodeF Value="0"></NodeF>
      </NodeE>
      <NodeE Name="ValueDEF">
        <NodeF Value="0"></NodeF>
      </NodeE>
    </NodeD>
  </NodeC>
</NodeA>

スタイルシート #1

<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:strip-space elements="*"/>

  <!--
  Identity transform: copy elements and attributes from input file as is
  -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <!--
  Drop <NodeE> elements with a preceding <NodeE> sibling that has the same
  @Name attribute value as the current element
  -->
  <xsl:template
    match="NodeE[preceding-sibling::NodeE[@Name = current()/@Name]]"/>

</xsl:stylesheet>

出力 #1

<?xml version="1.0" encoding="utf-8"?>
<NodeA NodeAattr="123">
  <NodeB NodeBattr="456"/>
  <NodeC>
    <NodeD Name="ValueD">
      <NodeE Name="ValueABC">
        <NodeF Value="0"/>
      </NodeE>
    </NodeD>
    <NodeD>
      <NodeE Name="ValueABC">
        <NodeF Value="0"/>
      </NodeE>
      <NodeE Name="ValueDEF">
        <NodeF Value="0"/>
      </NodeE>
    </NodeD>
  </NodeC>
</NodeA>

一方、<NodeE>ドキュメント全体で要素が重複していると見なす必要がある場合は、Muenchian グループ化を使用できます。

スタイルシート #2

<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:strip-space elements="*"/>

  <xsl:key name="kNode" match="NodeE" use="@Name"/>

  <!--
  Identity transform: copy elements and attributes from input file as is
  -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <!--
  Use Muenchian grouping to apply unique NodeE elements.
  See http://www.jenitennison.com/xslt/grouping/muenchian.html
  -->
  <xsl:template match="NodeE[generate-id() = 
                       generate-id(key('kNode', @Name)[1])]">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Drop other <NodeE> elements -->
  <xsl:template match="NodeE"/>

</xsl:stylesheet>

出力 #2

<?xml version="1.0" encoding="utf-8"?>
<NodeA NodeAattr="123">
  <NodeB NodeBattr="456"/>
  <NodeC>
    <NodeD Name="ValueD">
      <NodeE Name="ValueABC">
        <NodeF Value="0"/>
      </NodeE>
    </NodeD>
    <NodeD>
      <NodeE Name="ValueDEF">
        <NodeF Value="0"/>
      </NodeE>
    </NodeD>
  </NodeC>
</NodeA>
于 2013-04-10T13:03:08.493 に答える
-1

「deep-euql」関数を使用して、2 つの item() を比較します。これを確認してください:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

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

  <xsl:template match="NodeE">
    <xsl:choose>
      <xsl:when test="deep-equal(self::NodeE, following-sibling::NodeE)"/>
      <xsl:otherwise>
        <xsl:copy>
          <xsl:apply-templates select="* | @*"/>
        </xsl:copy>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
于 2013-04-10T13:01:18.020 に答える