Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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
让XSLT1.0在创建XML时牢记模式_Xml_Xslt_Xsd - Fatal编程技术网

让XSLT1.0在创建XML时牢记模式

让XSLT1.0在创建XML时牢记模式,xml,xslt,xsd,Xml,Xslt,Xsd,我正在转换不包含模式中所有元素的XML文件。我应该在XSLT文件中使用什么技术,以便生成的XML包含模式中指定的所有元素 我知道XSLT2.0可能很容易解决这个问题,但我还是坚持使用XSLT1.0 保罗 下面是我正在尝试做的一个例子: Schema.xml <SAN> <STACKMEMBERS> <STACKMEMBER> <A/> <B/>

我正在转换不包含模式中所有元素的XML文件。我应该在XSLT文件中使用什么技术,以便生成的XML包含模式中指定的所有元素

我知道XSLT2.0可能很容易解决这个问题,但我还是坚持使用XSLT1.0

保罗


下面是我正在尝试做的一个例子:

Schema.xml

<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A/>
            <B/>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C/>
                    <D/>
                    <E/>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>
<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A>1111</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>3333</D>
                    <E>4444</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>5555</D>
                    <E>6666</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A>2222</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>7777</D>
                    <E>8888</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>9999</D>
                    <E>1010</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>

DataFile.xml

<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A/>
            <B/>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C/>
                    <D/>
                    <E/>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>
<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A>1111</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>3333</D>
                    <E>4444</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>5555</D>
                    <E>6666</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A>2222</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>7777</D>
                    <E>8888</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>9999</D>
                    <E>1010</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>

1111
3333
4444
5555
6666
2222
7777
8888
9999
1010
所需输出:

<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A>1111</A>
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />
                    <D>3333</D>
                    <E>4444</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <C />
                    <D>5555</D>
                    <E>6666</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A>2222</A>
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />               
                    <D>7777</D>
                    <E>8888</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <C />
                    <D>9999</D>
                    <E>1010</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>
<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A>1111</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>3333</D>
                    <E>4444</E>
                    </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>5555</D>
                    <E>6666</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A />
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />
                    <D />
                    <E />
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A>2222</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>7777</D>
                    <E>8888</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>9999</D>
                    <E>1010</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A />
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />
                    <D />
                    <E />
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>

1111
3333
4444
5555
6666
2222
7777
8888
9999
1010
我当前的XSLT文件是…

<?xml version="1.0" encoding="windows-1252"?>

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="schemaFile" select="document('Schema.xml')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*">
        <SAN>
            <STACKMEMBERS>
                <xsl:for-each select="/SAN/STACKMEMBERS/STACKMEMBER">
                    <xsl:copy-of select="."/>
                    <xsl:copy-of select="$schemaFile/SAN/STACKMEMBERS/STACKMEMBER"/>
                </xsl:for-each>
            </STACKMEMBERS>
        </SAN>
    </xsl:template>

</xsl:stylesheet>

…它给了我错误的结果:

<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A>1111</A>
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />
                    <D>3333</D>
                    <E>4444</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <C />
                    <D>5555</D>
                    <E>6666</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A>2222</A>
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />               
                    <D>7777</D>
                    <E>8888</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <C />
                    <D>9999</D>
                    <E>1010</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>
<SAN>
    <STACKMEMBERS>
        <STACKMEMBER>
            <A>1111</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>3333</D>
                    <E>4444</E>
                    </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>5555</D>
                    <E>6666</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A />
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />
                    <D />
                    <E />
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A>2222</A>
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <D>7777</D>
                    <E>8888</E>
                </ETHERNETSWITCH>
                <ETHERNETSWITCH>
                    <D>9999</D>
                    <E>1010</E>
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
        <STACKMEMBER>
            <A />
            <B />
            <ETHERNETSWITCHES>
                <ETHERNETSWITCH>
                    <C />
                    <D />
                    <E />
                </ETHERNETSWITCH>
            </ETHERNETSWITCHES>
        </STACKMEMBER>
    </STACKMEMBERS>
</SAN>

1111
3333
4444
5555
6666
2222
7777
8888
9999
1010
请注意,元素B和C在模式中定义,但在数据文件中不存在。所需的输出会将仅包含在模式中的元素添加到数据文件中

对于一个选择,最好有多个条件(比如select=(一,二))。我觉得我离这里很近,但需要一点推动才能得到想要的输出

保罗


下面是完整的XSLT文件,使用Michael Kay的模板进行了修订,但不太有效:

<?xml version="1.0" encoding="windows-1252"?>

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:variable name="Instance" select="/"/>
    <xsl:variable name="Schema" select="document('schema.xml')"/>

    <xsl:template match="*">
        <xsl:copy>
            <xsl:variable name="E" select="."/>
            <xsl:variable name="S" select="$Schema//*[name(.)=name($E)]"/>
            <xsl:for-each select="$S/*">
                <xsl:variable name="SC" select="."/>
                <xsl:variable name="EC" select="$E/*[name(.)=name($SC)]"/>
                <xsl:choose>
                    <xsl:when test="$EC">
                        <xsl:apply-templates select="$EC"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="$SC"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>


我编写了一个模板,它应该返回元素的XPath。然后我修改了上面的模板,用XPath而不是元素名查找元素。结果是堆栈溢出,我不知道哪里出错了

下面是不起作用的XSLT代码。任何帮助都将不胜感激

保罗


没有简单的答案。只需编写一个输出有效XML的转换


周围有一些映射工具,例如Altova,它们试图自动化创建从模式a转换到模式B的样式表的任务。我从未发现它们非常有用,但它们可能适合您。

对。很高兴知道您的模式是用您自己发明的专有模式语言编写的。我想我们必须猜测语义,但它们似乎很简单。由于这种模式语言似乎只能表示序列,而不能表示选择或迭代,因此问题可能比使用更传统的模式语言更简单

在我看来,您要应用的规则是:

要处理实例中名为N的元素E,请执行以下操作: