Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT将XML转换为以前的XSD版本_Xml_Xslt_Xpath_Xsd - Fatal编程技术网

使用XSLT将XML转换为以前的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

我找了几天都没有成功

我想将一个与我上一个XSD版本匹配的XML文件转换为一个XML文件,该文件将由以前的XSD版本验证。我的第一个想法是使用XSLT

但我希望避免生成一个庞大的XSLT文件来过滤所有新元素

我想这是很平常的事情,应该可以自动完成

例如:

这是xsd的第一个版本

<?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的答案?另外,你没有回答我在上面的评论中提出的问题。