2

重複の可能性:
別の XML に存在する場合、XML 要素の属性を置き換えるための XSLT?

私は2つのXMLを持っています:

最初の XML:

<FirstXML>
  <catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
  </catalog>
</FirstXML>

2 番目の XML:

<SecondXML>
  <catalog>
         <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
  </catalog>
</SecondXML>

XSLT を使用して最初の XML を変換したいと考えています。最初の xml の cd ノードは、2 番目の xml の cd ノードに置き換える必要があります。

XSLT 変換の結果の XML:

<FirstXML>
  <catalog>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
  </catalog>
</FirstXML>

このための XSLT を手伝ってください。2 番目の XML をパラメーターとして XSLT に渡す必要があると思います。私はそうしようとしています。私は XSLT に非常に慣れていないため、正しくコーディングしていない可能性があります。これを行う方法についての情報は役に立ちます。前もって感謝します。

4

3 に答える 3

6

2 番目の XML をパラメーターとして XSLT に渡す必要があると思います。

これは可能ですが、まったく必要ありません

より便利な方法は、ドキュメントへのファイル パスのみを変換に渡し、XSLTdocument()関数を使用して解析およびアクセスすることです。

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

 <xsl:param name="pDocLink" select=
  "'file:///c:/temp/delete/SecondXml.xml'"/>

 <xsl:template match="/*">
  <xsl:copy>
   <xsl:copy-of select="document($pDocLink)/*/*[1]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された「最初の」ドキュメントに適用される場合:

<FirstXML>
    <catalog>
        <cd>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
            <country>USA</country>
            <company>Columbia</company>
            <price>10.90</price>
            <year>1985</year>
        </cd>
    </catalog>
</FirstXML>

「2番目の」ドキュメントは次の場所に配置されます:c:\temp\delete\SecondXml.xml :

<SecondXML>
    <catalog>
        <cd>
            <title>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
            <country>UK</country>
            <company>CBS Records</company>
            <price>9.90</price>
            <year>1988</year>
        </cd>
    </catalog>
</SecondXML>

必要な正しい結果が生成されます。

<FirstXML>
   <catalog>
      <cd>
         <title>Hide your heart</title>
         <artist>Bonnie Tyler</artist>
         <country>UK</country>
         <company>CBS Records</company>
         <price>9.90</price>
         <year>1988</year>
      </cd>
   </catalog>
</FirstXML>
于 2012-07-04T16:15:57.853 に答える
1

document()あなたは関数を見ているは​​ずです。パラメータが機能するようにXMLツリーを渡すことは、一部のXMLシステムであり、他のシステムではありません。

次のような変数がある場合

<xsl:variable name="source" select="document('filename.xml')//catalog"/>

次に、変数にアクセスする$sourceと、CDブランチのルートが得られます

編集

Dimitre Novatchevに対する私の答えを明確にするために、そして私が言ったように、それは可能ですが、90%の場合、ドキュメント関数を使用したいと思うでしょうが、ノードフラグメントをC#からスタイルシートに渡すことができます。 AddParamを使用したアプリケーションであり、独自のアプリケーションからそのデータを生成していて、データを書き込む必要がない場合(または実用的でない場合)に使用できます。

したがって、次のようなスタイルシートの場合:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
        <xsl:output method="xml" indent="yes"/>

        <xsl:param name="bonnie_tyler"/>

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

        <xsl:template match="cd[ancestor::FirstXML]">
                <xsl:copy>
                    <xsl:apply-templates select="msxsl:node-set($bonnie_tyler)//cd/*"/>
                </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

元の質問の1番目と2番目のXMLでは、次のようなノードのパスを使用できます。

        try
        {
            XslCompiledTransform xt = new XslCompiledTransform();
            Assembly ass = Assembly.GetEntryAssembly();
            Stream strm = ass.GetManifestResourceStream("ConsoleApplication1.testparam.xslt");
            XmlTextReader xmr = new XmlTextReader(strm);
            xt.Load(xmr);
            xmr.Close();

            XmlDocument originalDocument = new XmlDocument();
            strm = ass.GetManifestResourceStream("ConsoleApplication1.FirstXML.xml");
            originalDocument.Load(strm);
            XmlDocument replacementNode = new XmlDocument();
            strm = ass.GetManifestResourceStream("ConsoleApplication1.SecondXML.xml");
            replacementNode.Load(strm);

            XsltArgumentList arg = new XsltArgumentList();
            arg.AddParam("bonnie_tyler", "", replacementNode);

            StringBuilder htmlOutput = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(htmlOutput);

            xt.Transform(originalDocument, arg, writer);

            Console.Out.Write(htmlOutput.ToString());
        }

これにより、目的の出力が得られます(ただし、ここのようにディスクからファイルをロードすることはありません)。

于 2012-07-04T12:54:47.643 に答える
1

関数がありdocument、それを使用して複数の入力ソースを操作します。問題の説明が曖昧すぎて、より詳細な推奨事項を作成できません。http://www.ibm.com/developerworks/xml/library/x-tipcombxslt/など、いくつかのチュートリアルを検索してみてください。

于 2012-07-04T12:48:59.343 に答える