XSLT:将命名空间设置为第一个属性
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 样式表中的根节点预编码为
<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 )
}
有人可以帮我解决这个问题吗?
谢谢
I have a problem with namespace position in result xml file after xsl transformation.
My transformation stylesheet looks like
<?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>
In output xml file I want to get root node as
<SmartDriveUpdates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd">
But instead I have
<SmartDriveUpdates xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
I also tried to precode root node in xsl stylesheet as
<SmartDriveUpdates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd">
...
</SmartDriveUpdates>
But I get the same wrong result.
Transformation aplied to xml file by using Transform method from system.xml.xsl.xslcompiledtransform .NET class. I use PowerShell for this purpose:
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 )
}
Can someone help me to resolve this?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
命名空间定义和属性的顺序取决于实现。
您有两个选择:
使用另一个 XSLT 处理器 - Saxon 6.5.4 或 Saxon 9.x(有 .NET 版本)、某些版本的 Altova (XML-SPY) 和 XQSharp 都会根据需要生成输出。
继续使用 XslCompiledTransform,但实现您自己的 XmlWriter 对象。您可以自由地实现 WriteElementString Method(),以任何所需的方式生成元素的序列化。
The order of namespace definitions and attributes is implementation dependent.
You have two choices:
Use another XSLT processor -- Saxon 6.5.4 or Saxon 9.x (there is a .NET version), some versions of Altova (XML-SPY) and XQSharp all generate the output as desired.
Continue using XslCompiledTransform, but implement your own XmlWriter object. You have the freedom in the implementation of the WriteElementString Method() to produce the element's serialization in any way desired.
属性和名称空间声明属性的顺序并不重要,我认为您在使用 XSLT 时无法定义该顺序。为什么顺序对你很重要?
The order of attributes and of namespace declarations attributes does not matter and I don't think you can define that order when you use XSLT. Why does the order matter to you?
如果您不想放弃 XslCompiledTransform,您可以使用 XQSharp 的 XmlWriter 实现,而不是编写自己的实现,这可能会产生您正在寻找的结果,
If you don't want to abandon XslCompiledTransform, you can use XQSharp's XmlWriter implementations rather than writing your own, which may produce the result you are looking for,