使用XSLT将XML转换为以前的XSD版本
我找了几天都没有成功 我想将一个与我上一个XSD版本匹配的XML文件转换为一个XML文件,该文件将由以前的XSD版本验证。我的第一个想法是使用XSLT 但我希望避免生成一个庞大的XSLT文件来过滤所有新元素 我想这是很平常的事情,应该可以自动完成 例如: 这是xsd的第一个版本使用XSLT将XML转换为以前的XSD版本,xml,xslt,xpath,xsd,Xml,Xslt,Xpath,Xsd,我找了几天都没有成功 我想将一个与我上一个XSD版本匹配的XML文件转换为一个XML文件,该文件将由以前的XSD版本验证。我的第一个想法是使用XSLT 但我希望避免生成一个庞大的XSLT文件来过滤所有新元素 我想这是很平常的事情,应该可以自动完成 例如: 这是xsd的第一个版本 <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" element
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
<xs:element name="Customers">
<xs:complexType>
<xs:sequence>
<xs:element ref="Customer" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="Number" type="xs:integer"/>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:element name="Street" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
<xs:element name="ZIP" type="xs:string"/>
<xs:element name="State" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
然后我更新此XSD以获得版本2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.0">
<xs:element name="Customers">
<xs:complexType>
<xs:sequence>
<xs:element ref="Customer" maxOccurs="unbounded"/>
<xs:element ref="Animal" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="Number" type="xs:integer"/>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:element name="Street" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
<xs:element name="ZIP" type="xs:string"/>
<xs:element name="State" type="xs:string"/>
<xs:element name="Country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Age" type="xs:integer"/>
</xs:sequence>
<xs:attribute name="Rate" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Animal">
<xs:complexType>
<xs:sequence>
<xs:element name="Type" type="xs:string"/>
<xs:element name="Age" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<Customers xsi:noNamespaceSchemaLocation="Version2.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Customer Rate="24">
<Number>0</Number>
<FirstName>One</FirstName>
<LastName>Two</LastName>
<Address>
<Street>Three</Street>
<City>Four</City>
<ZIP>Five</ZIP>
<State>Six</State>
<Country>Seven</Country>
</Address>
<Age>0</Age>
</Customer>
<Customer Rate="18">
<Number>1</Number>
<FirstName>Twice</FirstName>
<LastName>Last</LastName>
<Address>
<Street>Kartofel</Street>
<City>Berlin</City>
<ZIP>4127</ZIP>
<State>Berlin</State>
<Country>Germany</Country>
</Address>
<Age>40</Age>
</Customer>
<Customer Rate="20">
<Number>2</Number>
<FirstName>First</FirstName>
<LastName>Test</LastName>
<Address>
<Street>Roosevelt</Street>
<City>New York</City>
<ZIP>6521</ZIP>
<State>New York</State>
<Country>USA</Country>
</Address>
<Age>56</Age>
</Customer>
<Animal>
<Type>Dog</Type>
<Age>5</Age>
</Animal>
</Customers>
我生成了一个与2.0版匹配的XML:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.0">
<xs:element name="Customers">
<xs:complexType>
<xs:sequence>
<xs:element ref="Customer" maxOccurs="unbounded"/>
<xs:element ref="Animal" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="Number" type="xs:integer"/>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:element name="Street" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
<xs:element name="ZIP" type="xs:string"/>
<xs:element name="State" type="xs:string"/>
<xs:element name="Country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Age" type="xs:integer"/>
</xs:sequence>
<xs:attribute name="Rate" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Animal">
<xs:complexType>
<xs:sequence>
<xs:element name="Type" type="xs:string"/>
<xs:element name="Age" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<Customers xsi:noNamespaceSchemaLocation="Version2.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Customer Rate="24">
<Number>0</Number>
<FirstName>One</FirstName>
<LastName>Two</LastName>
<Address>
<Street>Three</Street>
<City>Four</City>
<ZIP>Five</ZIP>
<State>Six</State>
<Country>Seven</Country>
</Address>
<Age>0</Age>
</Customer>
<Customer Rate="18">
<Number>1</Number>
<FirstName>Twice</FirstName>
<LastName>Last</LastName>
<Address>
<Street>Kartofel</Street>
<City>Berlin</City>
<ZIP>4127</ZIP>
<State>Berlin</State>
<Country>Germany</Country>
</Address>
<Age>40</Age>
</Customer>
<Customer Rate="20">
<Number>2</Number>
<FirstName>First</FirstName>
<LastName>Test</LastName>
<Address>
<Street>Roosevelt</Street>
<City>New York</City>
<ZIP>6521</ZIP>
<State>New York</State>
<Country>USA</Country>
</Address>
<Age>56</Age>
</Customer>
<Animal>
<Type>Dog</Type>
<Age>5</Age>
</Animal>
</Customers>
我想使用XSLT转换我的XML,使其通过我的XSD版本1.0进行验证。
我知道我可以添加标识模板,并为每个新节点或属性添加模板。但我想知道XPATH中的正则表达式或其他任何东西是否可以帮助我实现这一点。我的意思是,这个示例非常容易删除几个元素,但是如果我的XSD包含数千个元素,有没有办法轻松生成XSLT
提前感谢目前,XSD 2.0版很难阅读,但据我所知,新模式中唯一的变化是更多的元素和属性 注意:以下是一般性建议,与您的问题一样一般。如果你希望得到更具体的答案,那么,你知道该怎么做 但我想知道XPATH或 其他任何东西都可以帮我做这件事 视情况而定。鉴于我们不知道您提到的所有数千个元素,有两种情况是可能的:要么新元素和属性有规律性,即它们有很多共同点,要么更改是任意的,彼此无关 删除类似的元素和属性 如果模式的第二个版本中引入的元素和属性是相似的,您确实可以加快它们的删除速度,因为不必在模板中提及每个元素和属性。例如,如果所有新元素都位于相同的、以前未使用的命名空间中:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:new="http://www.newnamespace.com">
<xsl:template match="new:*"/>
<!--...-->
</xsl:stylesheet>
删除没有共同点的任意元素
在这种情况下,您必须依赖您已经找到的方法:
我知道我可以添加身份模板,并为每个新用户添加模板
节点或属性
当然,每个元素或属性不需要单独的模板
<xsl:template match="Animal | Monument | Otherunwantedstuff"/>
事实上,您正在寻找执行以下功能的工具: 找到两个XSD文件之间的本质区别忽略空格和CRLF! 评估更改对各自XML文件的影响 在实际的XML文件中执行更改 注意:如果删除元素或元素的“必需”方面,则存在一个基本问题 属性,该属性在旧XSD中是必需的。迁移 然后,将新XML转换为旧XML可能会导致需要添加 未知值 因此,您的函数必须是XMLSchema命名空间中的XSLT规范,从而在目标命名空间中生成XSLT规范 由此产生的XSLT并不长且复杂:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<html><textarea rows="20" cols="120"><xsl:apply-templates /></textarea></html>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="Customers">
<xsl:element name="{name()}">
<xsl:apply-templates select="Customer"/>
</xsl:element>
</xsl:template>
<xsl:template match="Customer">
<xsl:element name="{name()}">
<xsl:apply-templates select="Number"/>
<xsl:apply-templates select="FirstName"/>
<xsl:apply-templates select="LastName"/>
<xsl:apply-templates select="Address"/>
</xsl:element>
</xsl:template>
<xsl:template match="Address">
<xsl:element name="{name()}">
<xsl:apply-templates select="Street"/>
<xsl:apply-templates select="City"/>
<xsl:apply-templates select="ZIP"/>
<xsl:apply-templates select="State"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
如果不删除任何元素或属性,则可以从旧XSD派生此模板。旧XSD的XSLT必须按照每个父元素的复杂类型顺序使用指定的元素。您的XSD 2.0版太乱了。你能正确格式化它吗?另外,如果您可以基于XSD 2.0版生成XML,为什么不对第一个版本执行相同的操作?谢谢您的回答。@Luffy,欢迎您。如果对你有帮助,请考虑接受我的回答。谢谢你的回答。我可能不是很清楚。我正在寻找一种自动的方法,将使用XSD版本生成的XML文件转换为另一个经过此XSD以前版本验证的XML。我想使用旧的XSD版本将XML转换为有效的XML。例如,我发现:它解释了如何在XML中仅显示必填字段。我想知道是否存在等效的东西来转换XML以通过特定的XSD进行验证。您是否也阅读了Michael Kay的答案?另外,你没有回答我在上面的评论中提出的问题。