Question

Je ne peux pas être la première personne à le faire, il semble que ce serait une pratique si courante de fusionner deux documents en utilisant XSLT. Cependant, je n'arrive pas à trouver un seul exemple sur l'ol 'interweb.

J'ai deux documents XML qui sont récupérés sous forme de chaînes de XML de SQL Server. je veux utiliser XslCompiledTransform pour fusionner les deux documents. Je sais que XslCompiledTransform éteint le xsl document() fonction par défaut. J'ai tourné ça sur l'utilisation XsltSettings Quand je crée mon XslCompiledTransform objet.

Ma compréhension de la façon de "ajouter" le deuxième document à la transformation consiste à utiliser un XsltArgumentList et utilisez le AddParam() Méthode et ajouter un XPathNavigator objet:

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

Cependant, toute tentative d'accès au document qui est ajouté se traduit par une erreur ou rien de renvoyé. - 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 - Accédez uniquement au document ajouté, pas le document chargé de la transformation.

<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>

Je sais que je manque quelque chose d'évident, mais cela va au-delà de la frustration. Je sais que le document est ajouté en tant que paramètre, mais je ne trouve pas d'exemple sur la façon d'accéder à un document chargé en tant que paramètre.

Toute aide serait grandement appréciée. Gardez à l'esprit que le code ci-dessus est un travail en cours et se situe entre deux des centaines de tentatives pour le faire fonctionner donc si quelque chose semble un peu étrange, c'est probablement parce que c'est entre les tentatives.

Était-ce utile?

La solution

Vous devez définir un paramètre dans votre feuille de style, puis utiliser ce paramètre. Voici un exemple simple, la feuille de style ressemble à la suivante:

<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>

Le code C # ressemble à ce qui suit:

    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);

Il s'agit d'une application de console qui, pour la simplicité, écrit à console, mais vous pouvez bien sûr utiliser d'autres sorties que la méthode de transformation permet.

Cet exemple écrit alors <ul><li>1</li><li>2</li></ul> Le paramètre d'entrée a donc été traité.

Cela devrait donc vous montrer comment passer dans un paramètre que XSLCompiledTransform considère comme un ensemble de nœuds que vous pouvez traiter avec XSLT.

En ce qui concerne la rédaction d'une feuille de style qui fusionne deux documents, veuillez publier deux échantillons d'entrée et l'échantillon de résultat correspondant que vous souhaitez créer si vous avez des problèmes à écrire que XSLT.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top