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