xml - 您可以转换无序的 xml 以匹配 xsd :sequence order?

标签 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 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 的处理顺序是否得到保证。此外,这是在 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>

希望这对您有所帮助。

关于xml - 您可以转换无序的 xml 以匹配 xsd :sequence order?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7771462/

相关文章:

xslt - 如何根据层次结构级别删除重复项?

xml - 使用 XSLT 扩展 HTML5 视频元素

java - 无法解析符号 AppCompat

xml - 什么是 xs :NCName type and when should it be used?

XSLT:reocurring xpath的缩写

xsd - 从 RelaxNG 生成 XSD,同时保留根元素限制

xml - XSD 中的版权信息放在哪里?

java - Jaxb 元素属性选择

java - 用java居中一个XML创建的按钮

xml - 从 xsd 生成 cXML 类会引发错误 "The element ' uri :ds:Signature' is missing. "