0

次のような XML があります。

<LISTOFHARDWARE>
    <HARDWARE>
        <item>
            <SERIALNUMBER>D4242050101</SERIALNUMBER>
            <STATUS>2 </STATUS>
            <STATUSREASON>998 </STATUSREASON>
            <MACADDRESS />
            <LINKEDSMARTCARD>4135237101</LINKEDSMARTCARD>
            <PRODUCTDETAIL>
                <TYPE>DEVICE</TYPE>
                <MODEL>ABC123</MODEL>
            </PRODUCTDETAIL>
        </item>
        <item>
            <SERIALNUMBER>D4242050101</SERIALNUMBER>
            <STATUS>2 </STATUS>
            <STATUSREASON>998 </STATUSREASON>
            <MACADDRESS />
            <LINKEDSMARTCARD>4135237101</LINKEDSMARTCARD>
            <PRODUCTDETAIL>
                <TYPE>DEVICE</TYPE>
                <MODEL>ABC123</MODEL>
            </PRODUCTDETAIL>
        </item>
    </HARDWARE>
</LISTOFHARDWARE>   

結果が次のようになるように、要素を要素 (直接の親要素) に<item>置き換え、親要素を削除したいと思います。<HARDWARE><HARDWARE>

<LISTOFHARDWARE>
    <HARDWARE>
        <SERIALNUMBER>D4242050101</SERIALNUMBER>
        <STATUS>2 </STATUS>
        <STATUSREASON>998 </STATUSREASON>
        <MACADDRESS />
        <LINKEDSMARTCARD>4135237101</LINKEDSMARTCARD>
        <PRODUCTDETAIL>
            <TYPE>DEVICE</TYPE>
            <MODEL>ABC123</MODEL>
        </PRODUCTDETAIL>
    </HARDWARE>
    <HARDWARE>
        <SERIALNUMBER>D4242050101</SERIALNUMBER>
        <STATUS>2 </STATUS>
        <STATUSREASON>998 </STATUSREASON>
        <MACADDRESS />
        <LINKEDSMARTCARD>4135237101</LINKEDSMARTCARD>
        <PRODUCTDETAIL>
            <TYPE>DEVICE</TYPE>
            <MODEL>ABC123</MODEL>
        </PRODUCTDETAIL>

    </HARDWARE>
</LISTOFHARDWARE>   

<item>要素を含む任意の XML ファイルで機能する XSL 変換でこれを行う方法はありますか?

編集

この回答ともう少し調査した後、私はほとんどそこにいますが、完全ではありません。次の点を考慮してください。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!--  Replace <item> with name of parent element -->
    <xsl:template match="item">
        <xsl:element name="{name(..)}">
            <xsl:apply-templates select="@*|node()" />
        </xsl:element>
    </xsl:template>

    <!-- Remove immediate parent of <item> elements -->
    <xsl:template match="item/.."> <!-- Results in syntax error --> 
            <xsl:apply-templates select="@*|node()" />
    </xsl:template>

</xsl:stylesheet>

問題は、要素を親の名前に変更した後、親を動的に参照して要素<item>の親を削除できないことです。item

4

3 に答える 3

3

これを行う1つの方法は次のとおりです。

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

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

  <!-- Process any element that has "item" as child -->
  <xsl:template match="*[item]">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- Replace "item" with its parent in source XML -->
  <xsl:template match="item">
    <xsl:element name="{name(..)}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>
于 2013-09-19T13:00:05.353 に答える
1

最初に、変更を必要としない XML 内のすべてのノードをコピーするために使用できるIdentity Transformについて学習する必要があります。

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

あなたが実際に言っているのはitem要素を削除することだけなので、変換がうまくいくと思う方法を単純化する必要がありますが、その子は保持します。これを行うには、別の単純なテンプレートだけがサフィックスになります

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

これが行っているのは、 item要素の照合だけですが、 item要素自体をコピーせずにその子の処理を続行するだけです (子ノードは ID テンプレートによってコピーされるだけです)。

このXSLTを試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:template>
</xsl:stylesheet>
于 2013-09-19T12:52:42.957 に答える
1

これはどうですか?

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

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/*">
        <xsl:element name="{node-name(.)}">
            <xsl:for-each select="*/item">
                <xsl:element name="{node-name(..)}">
                  <xsl:copy-of select="./*" />
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

OP による編集:私の場合、関数node-name()をに変更するname()必要がありました。そうしないと、コンパイルされません。

于 2013-09-19T13:45:19.010 に答える