1

xslt は初めてで、xslt を使用して 2 つの xml を 1 つに結合する必要があります。最初の演習として、file1.xml、file2.xml、および transform.xslt の 3 つのファイルを作成し、file1.xml を直接実行してこれらをマージする方法を見つけました。これが私がやった方法です:

file1.xml で:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="transform.xslt"?>
<stuff>
    ...
</stuff>

file2.xml で:

<morestuff>
   ...
</morestuff>

transform.xslt で:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom-functions">
    <xsl:output method="xml" indent="yes" version="1.0" encoding="ISO-8859-1"/>
    <xsl:variable name="file2" select="document('file2.xml')" />
    <xsl:doing-stuff>
        ...
        <!-- contains references to $file2 -->
        ...
    </xsl:doing-stuff>
</xsl:stylesheet>

ただし、C# ASP.NET コードを使用して、xmlファイルの代わりに特定の xml文字列を使用してこれを行う必要があります。そのようです:

public string MergeXmls(string xml1, string xml2){
    string mergedXml;
    var xsltPath = HttpContext.Current.Server.MapPath("transform.xslt");
    //???
    return mergedXml;
}

どうすればこれを実現できますか? transform.xslt からへの参照を削除する必要があること document('file2.xml')はわかっていますが、そこからどこに行けばよいかわかりません。

4

2 に答える 2

1

XmlPreloadedResolverこれは、クラスを使用して実現できます。documentこれにより、XSLT で関数を解決するために使用されるエンティティをプリロードできます。

唯一の注意点は、関数で指定されたURI が XSLT ドキュメント自体のベース URI に関連するものとして扱われることです。そのため、ベース URI をオーバーライドできるようdocumentに、少し複雑な方法でロードする必要があります。XmlReader

public string MergeXml(string xml1, string xml2)
{
    XslCompiledTransform xslt = new XslCompiledTransform();
    XmlDocument xsltDoc = new XmlDocument();
    // Load the XSLT file through XmlReader to override the base URI.
    using( StreamReader reader = File.OpenText(HttpContext.Current.Server.MapPath("transform.xslt")) )
    using( XmlReader xmlReader = XmlReader.Create(reader, null, "file:///transform.xslt") )
    {
        xsltDoc.Load(xmlReader);
    }
    // Use XsltSettings to enable the use of the document() function.
    xslt.Load(xsltDoc, new XsltSettings(true, false), null);

    // Load the first XML file into a document
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml1);

    // Create the resolver and add the second file to it.
    XmlPreloadedResolver resolver = new XmlPreloadedResolver();
    resolver.Add(new Uri("file:///file2.xml"), xml2);

    using( StringWriter writer = new StringWriter() )
    using( XmlWriter xmlWriter = XmlWriter.Create(writer) )
    {
        // Pass the resolver to the transform
        xslt.Transform(doc, null, xmlWriter, resolver);
        return writer.ToString();
    }
}

このXmlPreloadedResolverクラスは .Net 4.0 以降でのみ使用できますが、以前のバージョンを使用している場合でも、カスタム クラスを派生させSystem.Xml.XmlResolverて同様の機能を自分で実装することができます。

于 2013-05-01T22:51:57.953 に答える
1

フロント エンドの Web ページでは、次のように System.Web.UI.WebControls.Xml オブジェクトを使用します。

<asp:Xml ID="xmlDisplay" runat="server" />

私の関数の背後にあるコードでは、次のようになります。

public void MergeXmls(string xml1, string xml2)
{
    string mergedXml = "<root>" + xml1 + xml2 + "</root>;
    xmlDisplay.DocumentContent = mergedXml;
    xmlDisplay.TransformSource = Server.MapPath("transform.xslt");
}

ページをロードすると、xmlDisplay オブジェクトは、mergedXml で見つかった XML 文字列から XSLT にデータをロードした結果を保持します。

ここで提供されるコード サンプルは、パラメーターとして渡された 2 つの文字列から有効な XML 文字列を作成することには対応していません。単純に 2 つを連結するだけで、場合によっては機能する可能性があります。

データ要素への XPath が mergedXml 文字列で見つかった要素へのパスと一致するように、XSLT を調整する必要があります。XSLT には、ソース XML データ ファイルへの参照がありません。

それが役立つことを願っています。

于 2013-05-01T22:44:34.587 に答える