XSLT:将名称空间设置为第一个属性

时间:2011-03-16 12:02:29

标签: xml xslt powershell namespaces transformation

xsl转换后,我在结果xml文件中的命名空间位置有问题。

我的转换样式表看起来像

<?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 stylesheet中的根节点预编码为

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

但我得到了同样错误的结果。

使用system.xml.xsl.xslcompiledtransform .NET类中的Transform方法将转换应用于xml文件。我为此目的使用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 个答案:

答案 0 :(得分:2)

属性和命名空间声明属性的顺序无关紧要,我不认为您在使用XSLT时可以定义该顺序。为什么订单对你很重要?

答案 1 :(得分:1)

命名空间定义和属性的顺序取决于实现

您有两种选择:

  1. 使用另一个XSLT处理器--Saxon 6.5.4或Saxon 9.x(有一个.NET版本),某些版本的Altova(XML-SPY)和XQSharp都可以根据需要生成输出。

  2. 继续使用XslCompiledTransform,但实现自己的XmlWriter对象。您可以自由地执行WriteElementString Method(),以任何方式生成元素的序列化。

答案 2 :(得分:0)

如果您不想放弃XslCompiledTransform,您可以使用XQSharp的XmlWriter实现,而不是自己编写,这可能会产生您想要的结果,