您可以转换无序的 xml 以匹配 xsd:sequence 顺序吗? [英] Can you transform unordered xml to match an xsd:sequence order?

查看:36
本文介绍了您可以转换无序的 xml 以匹配 xsd:sequence 顺序吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 xslt 将无序 xml 转换为 xsd 架构中指定的正确顺序

Hi i need to transform unorderd xml using xslt to the correct order as specified in an xsd schema

<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 转换为序列定义的正确顺序

The xml could have the properties in any order, with upwars of 10+ property elements.I have tried using an xsl:for-each to try and process the xml but i'm stumped at how to get the xslt to transform the xml into the correct order as defined by the sequence

任何帮助将不胜感激

推荐答案

这是一个 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 以匹配架构):

when this transformation is applied on the provided XML document (Person renamed to person to match the schema):

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

并且如果提供的 XML 架构在文件 c:\temp\delete\schema.xsd 中:

and if the provided XML schema is in the file 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>

这篇关于您可以转换无序的 xml 以匹配 xsd:sequence 顺序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆