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

Xml XSLT:将名称空间设置为第一个属性,xml,xslt,powershell,namespaces,transformation,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=

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>
有人能帮我解决这个问题吗


谢谢

属性和名称空间声明属性的顺序并不重要,我认为在使用XSLT时不能定义顺序。为什么顺序对您很重要?

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

你有两个选择:

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

  • 继续使用XslCompiledTransform,但实现自己的XmlWriter对象。您可以自由地实现WriteElementString方法(),以任意方式生成元素的序列化


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

    好问题,+1。请参阅我的答案以了解解释和两种解决方案。我知道,但我们有一些合并工具,可以在转换后合并这些文件,如果找不到命名空间作为第一个节点,则会崩溃:(如果你有依赖属性顺序的东西,它会被破坏,如果你对它有任何控制权,你应该修复它。同意。任何依赖属性处于特定顺序的工具都应该发送回其制造商,并要求退款。将XML描述为错误的,而不是消费它的工具,是错误的想法hanks,我将尝试使用自己的XmlWriter或修复我们的合并工具。
    <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">
    
    <SmartDriveUpdates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LightSpeedXMLSchema.xsd">
      ...
    </SmartDriveUpdates>
    
    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 )
    }