Объединение двух xpathdocuments с использованием xmlcompiledtransform

StackOverflow https://stackoverflow.com/questions/2365295

Вопрос

Я не могу быть первым, кто это сделал, кажется, что было бы такой обычной практикой объединять два документа с использованием XSLT. Тем не менее, я не могу найти ни одного примера на Ol 'Interweb.

У меня есть два XML -документа, которые получаются как строки XML с SQL Server. Я хочу использовать XslCompiledTransform чтобы объединить два документа. я знаю это XslCompiledTransform Выключает XSL document() Функция по умолчанию. Я включил это на использование XsltSettings Когда я создаю свой XslCompiledTransform объект.

Насколько я понимаю, как «добавить» второй документ к преобразованию - использовать XsltArgumentList и используйте 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>

Я знаю, что упускаю что -то очевидное, но это выходит за рамки разочарования. Я знаю, что документ добавляется в качестве параметра, но я не могу найти пример того, как получить доступ к документу, загруженный как параметр.

Любая помощь будет очень оценена. Имейте в виду, что приведенный выше код находится в стадии разработки и находится между двумя из сотен попыток заставить его работать, поэтому, если что -то выглядит немного странно, это, вероятно, потому, что между попытками.

Это было полезно?

Решение

Вам нужно определить параметр в своей таблице стилей, а затем использовать этот параметр. Вот простой пример, таблица стиля выглядит следующим образом:

<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, но вы, конечно, можете использовать другие выходы, которые позволяет метод преобразования.

Этот пример затем пишет <ul><li>1</li><li>2</li></ul> Таким образом, входной параметр был обработан.

Так что это должно показать вам, как пройти в параметре, который XslCompiledTransform считает как набор узлов, который вы можете обработать с помощью XSLT.

Что касается написания таблицы стилей, которая объединяет два документа, пожалуйста, опубликуйте два образца ввода и соответствующий образец результатов, который вы хотите создать, если у вас есть проблемы с написанием этого XSLT.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top