您能转换无序的xml以匹配xsd:sequence顺序吗?
您好,我需要使用xslt将无序xml转换为xsd模式中指定的正确顺序您能转换无序的xml以匹配xsd:sequence顺序吗?,xml,xslt,xsd,Xml,Xslt,Xsd,您好,我需要使用xslt将无序xml转换为xsd模式中指定的正确顺序 <Person> <property name="address" value="5" /> <property name="firstname" value="1234567890" /> <property name="lastname" value="The BFG" /> </Person> 需要使用 <xs:element
<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个属性元素。我曾尝试使用xsl:for-each来尝试和处理xml,但如何让xslt将xml转换为序列定义的正确顺序让我感到困惑
任何帮助都将不胜感激这可能不是最好的方法,但似乎效果不错。但是我不确定
xs:element
的处理顺序是否得到保证。此外,这是一个XSLT2.0答案,在氧气中使用Saxon HE 9.3.0.5进行测试
XML输入(修改了Person
的大小写以匹配模式):
外部XSD架构文件(Schema.XSD):
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>
1234567890
BFG
5.
希望这能有所帮助。这里有一个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>
<person>
<firstname>1234567890</firstname>
<lastname>The BFG</lastname>
<address>5</address>
</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>
然后生成所需的正确结果:
<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>
<person>
<firstname>1234567890</firstname>
<lastname>The BFG</lastname>
<address>5</address>
</person>
1234567890
BFG
5.
模式中的顺序知识可以硬编码到XSLT样式表中,还是必须从模式中发现?此外,XML和模式之间的Person
案例不匹配;这是打字错误吗?
<person>
<firstname>1234567890</firstname>
<lastname>The BFG</lastname>
<address>5</address>
</person>