Как связать / вложить XSL-преобразования в .NET - PullRequest
3 голосов
/ 16 сентября 2010

Контекст: .NET Framework 3.5

Я понимаю, как можно выполнить одно преобразование XML с помощью XSLT, но не нашел хороших примеров объединения цепочек преобразований XML.

Ввод: -XML-документ как XPathDocument.- Пути к нескольким файлам XSL.

Ожидаемый результат: - предпочтительно XPathDocument / IXPathNavigable, представляющий XML со всеми примененными преобразованиями, одно за другим.

Пример сценария :

input xml: <doc></doc>

xsl-1: .xsl, который добавляет <one /> в качестве дочернего элемента элемента doc.xsl-2: .xsl, который добавляет <two /> в качестве дочернего элемента документа.

Ожидаемый результат

<doc><one /><two /></doc>

Цели

Используйте только форвардную природу XPathDocument / IXPathNavigable или лучше.Избегайте загрузки всего документа в память.

Ответы [ 3 ]

2 голосов
/ 17 сентября 2010

Может быть что-то вроде следующего (я не пытался скомпилировать это):

XslCompiledTransform xsl1 = new XslCompiledTransform();
xsl1.Load("xsl1.xsl");

XslCompiledTransform xsl2 = new XslCompiledTransform();
xsl1.Load("xsl2.xsl");

using (Stream stream = new MemoryStream())
{
     using (XmlReader xmlReader1 = XmlReader.Create("source.xml"))
     {
          xsl1.Transform(xmlReader1, stream);
     }

     stream1.Position = 0;

     using (XmlReader xmlReader2 = XmlReader.Create(stream))
     {
         xsl2.Transform(xmlReader2, "output.xml");
     }
}

Используя xmlreader, вы получите форвард, который только ищете.Я только что передал первый результат в MemoryStream, но вы могли бы сделать это для временного файла.

Для этого дополнительного небольшого количества производительности вы можете посмотреть на предварительную компиляцию xslt.

XSLT-компилятор (xsltc.exe)

0 голосов
/ 20 сентября 2010

I.Это демонстрирует, как выполнить многопроходные преобразования XSLT 1.0 с любым процессором XSLT 1.0 , который поддерживает функцию расширения exslt node-set (), включая .NET XslCompiledTransform.

Для других процессоров XSLT 1.0 необходимо заменить ext:node-set() на то, что они поддерживают, например msxsl:node-set() (с msxsl, связанным с правильным пространством имен) для MSXML.

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ext="http://exslt.org/common"
    exclude-result-prefixes="ext xsl">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
   <xsl:apply-templates select="node()"/>
  </xsl:variable>

  <xsl:apply-templates mode="pass2"
   select="ext:node-set($vrtfPass1)/node()"/>
 </xsl:template>

 <xsl:template match="/*">
     <xsl:copy>
       <xsl:copy-of select="@*"/>
       <one/>
     <xsl:apply-templates/>
     </xsl:copy>
 </xsl:template>

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

 <xsl:template match="/*/one" mode="pass2" >
     <xsl:call-template name="identity"/>
      <two/>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к этому XML-документу :

<doc/>

желаемый результат получается :

<doc>
   <one/>
   <two/>
</doc>

II. В настоящее время XSLT 1.0 и XSLT 2.0 используют XPath, и для этого требуется, чтобы весь XML-документ (представление) находился в оперативной памяти .

Рабочий проект для XSLT 2.1 (недавно переименованный в 3.0) предлагает новую функцию потоковой передачи , которая, если этот WD станет официальной рекомендацией, позволит совместимым процессорам XSLT 3.0 реализоватьпотоковое вещание.

III.XslCompiledTransform для XPathDocument по-прежнему содержит все представление XML-документа в памяти .Тот факт, что XPathDocument обеспечивает итерацию только вперед, не означает, что XslCompiledTransform выполняет потоковую передачу документа XML.

0 голосов
/ 17 сентября 2010

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

Существует подход, называемый Потоковые преобразования для XML (STX) , который не требует построения дерева в памяти.Возможно, вы захотите проверить STX проект на SourceForge.

Для обзора потоковых преобразований я рекомендую следующую статью:

Введение в потоковые преобразования для XML

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...