XSLT: установить пространство имен в качестве первого атрибута - PullRequest
4 голосов
/ 16 марта 2011

У меня проблема с положением пространства имен в XML-файле результата после преобразования xsl.

Моя таблица стилей преобразования выглядит как

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output indent="yes" method="xml" />
<xsl:template match="/">

<xsl:element name="SmartDriveUpdates">
  <xsl:attribute name="xsi:noNamespaceSchemaLocation">
    <xsl:text>LightSpeedXMLSchema.xsd</xsl:text>
  </xsl:attribute>
...
</xsl:element>

В выходном XML-файле я хочу получить корневой узел как

<SmartDriveUpdates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd">

Но вместо этого у меня есть

<SmartDriveUpdates xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Я также пытался предварительно кодировать корневой узел в таблице стилей xsl как

<SmartDriveUpdates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd">
  ...
</SmartDriveUpdates>

Но я получаю тот же неправильный результат.

Преобразование применено к XML-файлу с помощью метода Transform из класса .NET system.xml.xsl.xslcompiledtransform. Я использую PowerShell для этой цели:

Function Convert-WithXslt($originalXmlFilePath, $xslFilePath, $outputFilePath) {
## Simplistic error handling
$xslFilePath = Resolve-Path $xslFilePath
If( -not (Test-Path $xslFilePath) ) { 
    Throw "Can't find the XSL file" 
} 

$originalXmlFilePath = Resolve-Path $originalXmlFilePath
If( -not (Test-Path $originalXmlFilePath) ) { 
    Throw "Can't find the XML file" 
}

#$outputFilePath = Resolve-Path $outputFilePath
If( -not (Test-Path (Split-Path $originalXmlFilePath)) ) {
    Throw "Can't find the output folder" 
} 

## Get an XSL Transform object (try for the new .Net 3.5 version first)
$EAP = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"

$script:xslt = New-Object system.xml.xsl.xslcompiledtransform
Trap [System.Management.Automation.PSArgumentException] 
{  # no 3.5, use the slower 2.0 one
    $ErrorActionPreference = $EAP
    $script:xslt = New-Object system.xml.xsl.xsltransform
}
$ErrorActionPreference = $EAP

## load xslt file
$xslt.load( $xslFilePath )

## transform 
$xslt.Transform( $originalXmlFilePath, $outputFilePath )
}

Может кто-нибудь помочь мне решить эту проблему?

Спасибо

Ответы [ 3 ]

2 голосов
/ 16 марта 2011

Порядок атрибутов и атрибутов объявлений пространства имен не имеет значения, и я не думаю, что вы можете определить этот порядок при использовании XSLT.Почему заказ имеет значение для вас?

1 голос
/ 16 марта 2011

Порядок определений и атрибутов пространства имен зависит от реализации .

У вас есть два варианта:

  1. Используйте другой процессор XSLT - Saxon 6.5.4 или Saxon 9.x (есть версия .NET), некоторые версии Altova (XML-SPY) и XQSharp генерируют выходные данные по желанию. *

  2. Продолжайте использовать XslCompiledTransform, но реализуйте свой собственный объект XmlWriter. У вас есть свобода в реализации метода WriteElementString () для создания сериализации элемента любым желаемым способом.

0 голосов
/ 21 марта 2011

Если вы не хотите отказываться от XslCompiledTransform, вы можете использовать реализации XmlWriter XQSharp, а не писать свои собственные, что может привести к требуемому результату,

...