2

我不可能是第一个这样做的人,使用 XSLT 合并两个文档似乎是一种常见的做法。但是,我似乎无法在 ol' 互联网上找到一个示例。

我有两个 XML 文档作为 XML 字符串从 SQL Server 中检索。我想用来XslCompiledTransform合并这两个文件。我知道默认情况下XslCompiledTransform会关闭 XSLdocument()功能。我在XsltSettings创建XslCompiledTransform对象时使用了它。

我对如何将第二个文档“添加”到转换的理解是使用 anXsltArgumentList并使用该AddParam()方法并添加一个XPathNavigator对象:

XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam(
  (string)e.UserState + "s", "http://www.myuri.com/tabledata", 
  dataXmlDoc.CreateNavigator()
);

但是,任何尝试访问添加的文档都会导致错误或不返回任何内容。- C#:

XslCompiledTransform fieldToXhtmlTransform = new XslCompiledTransform(true);
try
{
  UriBuilder xsltUri = new UriBuilder(
    Request.Url.Scheme, Request.Url.Host, 
    Request.Url.Port, this.ResolveUrl("Transforms/address1.xslt")
  );

  XmlSecureResolver resolver = new XmlSecureResolver(
    new XmlUrlResolver(), new PermissionSet(PermissionState.Unrestricted)
  );
  fieldToXhtmlTransform.Load(
    xsltUri.ToString(), new XsltSettings(true, false), resolver
  );
}
catch
{
  //TODO: do something useful here. 
}

XPathDocument fieldSchemaXmlDoc = null;

using (MemoryStream fieldMemoryStream = new MemoryStream(
  Encoding.UTF8.GetBytes(e.Result.TableMetaDataXml)
))
{
  fieldSchemaXmlDoc = new XPathDocument(fieldMemoryStream);
}

XPathDocument dataXmlDoc = null;

using (MemoryStream dataMemoryStream = new MemoryStream(
  Encoding.UTF8.GetBytes(e.Result.DataXml)
))
{
  dataXmlDoc = new XPathDocument(dataMemoryStream);
}

StringBuilder output = new StringBuilder();

XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = true;
writerSettings.Encoding = Encoding.UTF8;

XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam(
  (string)e.UserState + "s", "http://www.myuri.com/tabledata",
  dataXmlDoc.CreateNavigator()
);    
XmlWriter transformedDataWriter = XmlWriter.Create(output, writerSettings);
fieldToXhtmlTransform.Transform(
  fieldSchemaXmlDoc, xsltArgs, transformedDataWriter
);

XSLT - 只访问添加的文档,而不是加载了转换的文档。

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:hlsschema="http://www.myuri.com/tableschema"
  xmlns:hlsdata="http://www.myuri.com/tabledata"
  exclude-result-prefixes="msxsl hlsschema hlsdata xsl"
>
  <xsl:output method="html" indent="yes"/>

  <p>
  <xsl:template match="hlsdata:Address1s">
    <xsl:for-each select="hlsdata:Address1">
      <p>
        <xsl:value-of select="hlsdata:dr_id"/>
      </p>
    </xsl:for-each>
  </xsl:template>
  </p>

</xsl:stylesheet>

XML

<hlsdata:Address1s 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:hlsdata="http://www.myuri.com/tabledata"
>
  <hlsdata:Address1>
    <hlsdata:dr_id>12345678</hlsdata:dr_id>
  </hlsdata:Address1>
</hlsdata:Address1s>

我知道我遗漏了一些明显的东西,但这不仅仅是令人沮丧。我知道文档被添加为参数,但我找不到如何访问作为参数加载的文档的示例。

任何帮助将不胜感激。请记住,上面的代码是一个正在进行的工作,并且是在数百次尝试中使其工作的两次之间,所以如果看起来有点奇怪,可能是因为它在尝试之间。

4

1 回答 1

4

您需要在样式表中定义一个参数,然后使用该参数。这是一个简单的示例,样式表如下所示:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:docs="http://example.com/2010/docs"
  exclude-result-prefixes="docs"
>
  <xsl:param name="docs:doc1" select="/.."/>

  <xsl:template match="/">
    <xsl:apply-templates select="$docs:doc1/node()"/>
  </xsl:template>

  <xsl:template match="root">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>

  <xsl:template match="foo">
    <li>
      <xsl:apply-templates/>
    </li>
  </xsl:template>
</xsl:stylesheet>

C# 代码如下所示:

    string xml = "<root><foo>1</foo><foo>2</foo></root>";
    XPathDocument doc = new XPathDocument(new StringReader(xml));

    XslCompiledTransform proc = new XslCompiledTransform();
    proc.Load(@"..\..\XSLTFile1.xslt");

    XsltArgumentList xsltArgs = new XsltArgumentList();
    xsltArgs.AddParam("doc1", "http://example.com/2010/docs", doc.CreateNavigator());

    proc.Transform(XmlReader.Create(new StringReader("<dummy/>")), xsltArgs, Console.Out);

这是一个控制台应用程序,为简单起见写入 Console.Out,但您当然可以使用 Transform 方法允许的其他输出。

然后该示例写入<ul><li>1</li><li>2</li></ul>,因此输入参数已被处理。

因此,这应该向您展示如何传入 XslCompiledTransform 视为您可以使用 XSLT 处理的节点集的参数。

至于编写合并两个文档的样式表,如果您在编写该 XSLT 时遇到问题,请发布两个输入示例和您想要创建的相应结果示例。

于 2010-03-03T11:32:16.633 回答