2011-10-14 56 views
3

嗨,我需要使用XSLT轉換unorderd XML以正確的順序爲XSD架構指定你可以變換無序的xml以匹配xsd:序列順序嗎?

<Person> 
    <property name="address" value="5" /> 
    <property name="firstname" value="1234567890" /> 
    <property name="lastname" value="The BFG" /> 
</Person> 

需要使用

<xs:element name="Person"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="firstname" type="xs:string"/> 
      <xs:element name="lastname" type="xs:string"/> 
      <xs:element name="address" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

的XML可以在任何順序屬性轉化,以及10多個屬性元素的upwars。我曾嘗試使用xsl:for-each來嘗試和處理xml,但我很難理解如何讓xslt將xml轉換爲正確的順序,如序列

任何幫助將不勝感激

+0

可以在架構中的順序的知識被硬編碼在XSLT樣式表,否則就必須從發現架構? – Dabbler

+0

此外,XML和模式之間存在「Person」的個案不匹配;這是一個錯字嗎? –

回答

1

這可能不是最好的方式,但它似乎工作正常。我不確定xs:element的訂單是否能夠得到保證。此外,這是一個在oXygen中使用Saxon-HE 9.3.0.5測試的XSLT 2.0答案。

XML輸入(改性的Person的情況下,以匹配模式):

<person> 
    <property name="address" value="5" /> 
    <property name="firstname" value="1234567890" /> 
    <property name="lastname" value="The BFG" /> 
</person> 

外部XSD模式文件(schema.xsd):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 
    <xs:element name="person"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="firstname" type="xs:string"/> 
     <xs:element name="lastname" type="xs:string"/> 
     <xs:element name="address" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

XSLT樣式表2.0:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="input"> 
    <xsl:copy-of select="/"/> 
    </xsl:variable> 

    <xsl:template match="/*"> 
    <xsl:variable name="firstContext" select="name()"/> 
    <xsl:variable name="xsdElems" select="document('schema.xsd')/xs:schema/xs:element[@name=$firstContext]/xs:complexType/xs:sequence/xs:element/@name"/> 
    <xsl:element name="{$firstContext}"> 
     <xsl:for-each select="$xsdElems"> 
     <xsl:variable name="secondContext" select="."/> 
     <xsl:element name="{$secondContext}"> 
      <xsl:value-of select="$input/*/*[@name=$secondContext]/@value"/> 
     </xsl:element> 
     </xsl:for-each>  
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

XML輸出:

<person> 
    <firstname>1234567890</firstname> 
    <lastname>The BFG</lastname> 
    <address>5</address> 
</person> 

希望這會有所幫助。

1

下面是一個XSLT 1.0溶液

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kxsElemByName" match="xs:element" use="@name"/> 

<xsl:variable name="vSchema" select= 
    "document('file:///c:/temp/delete/schema.xsd')"/> 

<xsl:variable name="vDoc" select="/"/> 

<xsl:template match="/*"> 
    <xsl:variable name="vElem" select="."/> 

    <xsl:for-each select="$vSchema"> 
    <xsl:apply-templates select= 
    "key('kxsElemByName', name($vElem))"> 
    <xsl:with-param name="pElement" select="$vElem"/> 
    </xsl:apply-templates> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template match="xs:element"> 
    <xsl:param name="pElement"/> 

    <xsl:element name="{name($pElement)}"> 
    <xsl:apply-templates mode="generate" 
     select="xs:complexType/xs:sequence/*"> 
    <xsl:with-param name="pParent" select="$pElement"/> 
    </xsl:apply-templates> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="xs:element" mode="generate"> 
    <xsl:param name="pParent"/> 
    <xsl:variable name="vProp" select= 
    "$pParent/property[@name = current()/@name]"/> 

    <xsl:element name="{$vProp/@name}"> 
    <xsl:value-of select="$vProp/@value"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔Person重命名爲person匹配的模式)應用於:

<person> 
    <property name="address" value="5" /> 
    <property name="firstname" value="1234567890" /> 
    <property name="lastname" value="The BFG" /> 
</person> 

,如果提供的XML模式位於文件c:\temp\delete\schema.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 
    <xs:element name="person"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="firstname" type="xs:string"/> 
     <xs:element name="lastname" type="xs:string"/> 
     <xs:element name="address" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

那麼想要的,正確的結果產生

<person> 
    <firstname>1234567890</firstname> 
    <lastname>The BFG</lastname> 
    <address>5</address> 
</person> 
相關問題