0

ある XML ファイルから別の XML ファイルにいくつかの要素の名前を変更して、いくつかの要素をコピーするための XSLT テンプレートの作成に成功しました。

ただし、要素を取得して XML 構造の別の部分に移動する方法がわかりません。

この XML を変換したい:

<Hosts>
    <Clusters>
        <Cluster>
            <Nodes>
                <WindowsHost/>
            </Nodes>
        </Cluster>
    </Clusters>
</Hosts>

に:

<Hosts>
    <WindowsHosts>
        <WindowsHost/>
    </WindowsHosts>
</Hosts>

現在作業中の XSLT には以下が含まれます。

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

<xsl:template match="/*">
    <xsl:copy>
        <xsl:apply-templates select="*"/>
    </xsl:copy>
</xsl:template>

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

...そして、次のようなテンプレートを繰り返します。

<xsl:template match="/Hosts/Clusters/Cluster/Nodes/WindowsHost">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/Hosts/Clusters/Cluster/Nodes/WindowsHost/SomeElement">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

等々。すべての要素がコピーされるわけではなく、一部の要素名が変更されるため、コピーされる各要素には独自のテンプレートがあります。しかし、完全な XPath ではなく、要素名の変更に成功しただけです。

どんな助けでも大歓迎です。

ポール


あなたの応答は大歓迎です。しかし、明確にするために、私の例は単純すぎると思います。

私の既存の XSLT には、ある XML から別の XML にコピーする必要があるすべての要素のテンプレートがあるため、多くのテンプレート (ほぼ 1000) があり、XSLT ファイルの先頭では、既定でどの要素にも何も起こらないようになっています。簡単に言えば、私はあなたの答えのテクニックを試してみましたが、成功しませんでした.

要素がコピーされるシナリオは 3 つあります。

  1. そのままコピペ
  2. 要素名をコピーして変更する
  3. スキーマ内の別の場所にコピーする

既存の XSLT ファイルは、#1 と #2 の両方で機能します。#3 仕事に行けない。XSLT ファイルの詳細はこちら

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

<xsl:template match="/*">
    <xsl:copy>
        <xsl:apply-templates select="*"/>
    </xsl:copy>
</xsl:template>

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

<xsl:template match="/SAN/ClientProfile">
<!-- copy element as is (working) -->
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/SAN/ClientProfile/Name">
<!-- copy element but change its name (working) -->
    <CompanyName>
        <xsl:apply-templates/>
    </CompanyName>
</xsl:template>

<xsl:template match="/SAN/EQLHosts/WindowsClusters/Cluster/ClusterNodes/WindowsHost">
<!-- copy to different part of schema (not working) -->
    <WindowsHost>
        <xsl:apply-templates/>
    </WindowsHost>
</xsl:template>

だから、私はに変更/SAN/EQLHosts/WindowsClusters/Cluster/ClusterNodes/WindowsHostしたい/SAN/EQLHosts/WindowsHosts/WindowsHost。この要素のすべての子は、既にコピーされている要素と同じ方法で処理されます。

私の説明が明確であることを願っています。この情報があなたの答えを変えるのか、それとも私がただ密集しているだけなのか教えてください.

ポール

4

2 に答える 2

1

本当に何かを動かしているようには見えません。いくつかの要素を無視して、新しい要素を追加するだけWindowsHostsです。単一のインデンティ変換を行い、テンプレートxsl:apply-templatesから選択したものを変更してみてください。/*

他の要素の名前を変更する必要がある場合は、その要素に特に一致する新しいテンプレートを追加してください。恒等変換は、既存の要素を変更せずにコピーするため、すべての要素にテンプレートを用意する必要はありません。

例:

XML 入力

<Hosts>
    <Clusters>
        <Cluster>
            <Nodes>
                <WindowsHost/>
            </Nodes>
        </Cluster>
    </Clusters>
</Hosts>

XSLT1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="/*">
        <xsl:copy>
            <WindowsHosts>
                <xsl:apply-templates select="@*|Clusters/Cluster/Nodes/WindowsHost"/>
            </WindowsHosts>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

出力

<Hosts>
   <WindowsHosts>
      <WindowsHost/>
   </WindowsHosts>
</Hosts>

編集

名前の変更を含む例を次に示します。上記の入力を使用して同じ出力を生成します...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="/*">
        <xsl:copy>
            <!--Start your select at the first element you need to output and/or modify.-->
            <xsl:apply-templates select="@*|Clusters/Cluster"/>
        </xsl:copy>
    </xsl:template>

    <!--Example rename-->
    <xsl:template match="Cluster">
        <WindowsHosts>
            <xsl:apply-templates select="@*|Nodes/WindowsHost"/>
        </WindowsHosts>
    </xsl:template>

</xsl:stylesheet>

編集#2

だから、私はに変更 /SAN/EQLHosts/WindowsClusters/Cluster/ClusterNodes/WindowsHostし たい/SAN/EQLHosts/WindowsHosts/WindowsHost。この要素のすべての子は、既にコピーされている要素と同じ方法で処理されます。

この場合、次の中から選択WindowsHostEQLHostsます...

<xsl:template match="EQLHosts">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <WindowsHosts>
            <xsl:apply-templates select="WindowsClusters/Cluster/ClusterNodes/WindowsHost"/>
        </WindowsHosts>
    </xsl:copy>
</xsl:template>

EQLHosts出力する必要がある他の子がある場合は、それを最初の に追加できますxsl:apply-templates。何かのようなもの:

<xsl:apply-templates select="@*|*[not(name()='WindowsClusters')]"/>
于 2013-05-23T23:53:18.060 に答える