2

ノード要素のデータをfile1.xmlからfile2.xmlにコピーする必要があります。 file1.xml

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <header>
    <AsofDate>31-Dec-2012</AsofDate>
    <FundName>This is Sample Fund</FundName>
    <Description>This is test description</Description>
  </header>
</root>

file2.xml

<?xml version="1.0" encoding="utf-8" ?>
<root id="1">
  <header id="2">
    <AsofDate id="3"/>
    <FundName id="4" />
    <Description id="5" />
  </header>
</root>

file1.xmlをfile2.xmlにマージした後、結果は次のようになります。

<?xml version="1.0" encoding="utf-8" ?>
<root id="1">
  <header id="2">
    <AsofDate id="3">31-Dec-2012</AsofDate>
    <FundName id="4">This is Sample Fund</FundName>
    <Description id="5">This is test description</Description>
  </header>
</root>

以下のXSLTを使用してファイルを変換しています。

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

以下は、変換を実行するために使用されるコードです。

    XslCompiledTransform tf = new XslCompiledTransform();
    tf.Load("TranFile.xsl");

    tf.Transform("file1.xml", "file2.xml");

ただし、上記のコードはfile2のコンテンツをfile1.xmlのコンテンツで上書きしています。これは単なるサンプルXMLです。実際には、ノードの名前とxmlファイルの階層はわかりません。ただし、ファイルとシナリオの両方で構造が同じになる場合は、まったく同じになります。私はXSLTを初めて使用しますが、結果を達成するためのこの正しいアプローチがあるかどうかはわかりません。XSLTを介して結果を達成することは本当に可能ですか。

4

1 に答える 1

4

私が投稿するソリューションは、次のことを念頭に置いて書かれています。

  • マージする必要があるのは属性だけです。テキストノードと要素ノードは、file1.xmlから表示されるとおりにコピーされます。

  • @id属性はfile2.xmlで順番に番号が付けられていないため、file2.xmlの@idは(たとえば)1 2 345の代わりに12143223312944になります。後者の場合は必要ありません。 file2.xmlを使用して、目的の出力を生成します。

  • document()関数を使用して、現在のファイルとは異なるファイルにアクセスできます。ドキュメント関数を使用しているときにXslCompiledTransformでエラーが発生する場合は、.NETでdocument()関数を使用してこれに従うことをお勧めします。XSLTはエラーを生成します。別のXSLTプロセッサ(xsltproc)を使用していますが、正常に動作します。

このソリューションは、外部ファイルへの参照を保持することに基づいているため、file1.xmlの要素を処理するたびに、参照はfile2.xmlの同じ要素を指すように移動されます。問題に応じて、両方のファイルが同じ要素階層を提示するため、これを行うことができます。

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

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

    <!-- Match the document node as an entry point for matching the files -->
    <xsl:template match="/">
        <xsl:apply-templates select="node()">
            <xsl:with-param name="doc-context" select="document('file2.xml')/node()" />
        </xsl:apply-templates>
    </xsl:template>

    <!-- In this template we copy the elements and text nodes from file1.xml and
         we merge the attributes from file2.xml with the attributes in file1.xml -->
    <xsl:template match="node()">
        <!-- We use this parameter to keep track of where we are in file2.xml by
             mimicking the operations that we do in the current file. So we are at
             the same position in both files at the same time. -->
        <xsl:param name="doc-context" />

        <!-- Obtain current position in file1.xml so we know where to look in file2.xml -->
        <xsl:variable name="position" select="position()" />

        <!-- Copy the element node from the current file (file1.xml) -->
        <xsl:copy>
            <!-- Merge attributes from file1.xml with attributes from file2.xml -->
            <xsl:copy-of select="@*|$doc-context[position() = $position]/@*" />
            <!-- Copy text nodes and process children -->
            <xsl:apply-templates select="node()">
                <xsl:with-param name="doc-context" select="$doc-context/node()" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
于 2013-02-20T23:49:56.540 に答える