XSLT преобразовать XML с пространством имен по умолчанию без добавления префикса? - PullRequest
7 голосов
/ 06 сентября 2010

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

Исходный файл XML:

<pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass">  

Я могу заставить его работать, добавив префикс в пространство имен по умолчанию (последнее), но как вывести XML без добавления префикса, это возможно с помощью XslCompiledTransform в .NET 4?

Ответы [ 3 ]

4 голосов
/ 06 сентября 2010

Я могу заставить его работать, добавив префикс к пространству имен по умолчанию ( последний), но как я мог вывести XML без добавления префикса, это возможно с помощью XslCompiledTransform в .NET 4?

Вот конкретный пример, как это сделать:

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns="http://workflow.converga.com.au/compass"
 xmlns:c="http://workflow.converga.com.au/compass"
 xmlns:ext="http://exslt.org/common"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 exclude-result-prefixes="c ext xsl">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pnewItem">
  <item name="wine">
   <price>3</price>
   <quantity>5000</quantity>
  </item>
 </xsl:param>

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

 <xsl:template match="c:item[last()]">
  <xsl:call-template name="identity"/>
  <xsl:copy-of select="ext:node-set($pnewItem)/*"/>
 </xsl:template>
</xsl:stylesheet>

при применении с XslCompiledTransform в следующем XML-документе :

<pExport xmlns="http://workflow.converga.com.au/compass">
 <Goods>
  <item name="tobacco">
   <price>5</price>
   <quantity>1000</quantity>
  </item>
 </Goods>
</pExport>

создает искомый (тот же XML-документ с добавленным новым элементом), правильный результат :

<pExport xmlns="http://workflow.converga.com.au/compass">
  <Goods>
    <item name="tobacco">
      <price>5</price>
      <quantity>1000</quantity>
    </item>
    <item name="wine">
      <price>3</price>
      <quantity>5000</quantity>
    </item>
  </Goods>
</pExport>
4 голосов
/ 09 сентября 2010

Ключом является использование атрибута exclude-result-prefixes в элементе stylesheet.

В этом разделе часто задаваемых вопросов XSLT есть несколько хороших объяснений.

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

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass">
  <xsl:template match="compass:pExport">
    <pExport>...</pExport>
  ...

Приведенный выше шаблон будет соответствовать вашему входному элементу XML - и созданный литерал элемента будет находиться в выходном пространстве имен по умолчанию (которое является тем же пространством имен).

Конечно, вы должны знать, что в XML префикс не имеет значения - два элемента идентичны, если они имеют одинаковое пространство имен и локальное имя, даже если два префикса определены для этого одного пространства имен.

<element xmlns="http://test.com"></element>
<ns01:element xmlns:ns01="http://test.com"></ns01:element>

Два приведенных выше элемента одинаковы, поскольку имеют одно и то же полное имя.

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