我认为提出这个问题的最好方法是:如何为输出中的根元素指定默认命名空间?这样做:
<xsl:template match="/">
<r xmlns:s"http://www.mycompany.com/s/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/default/schema" >
....
....
在Oracle中给我一个错误:
ORA-31011: XML Parsing Failed ORA-19201: Error occurred in in XML Processing LPX-00604: Invalid attribute 'nIfNotExist', for attribute 'name' ORA-06512: at SYS.XMLType at line 74 ORA-06512: at line 24
其中'nIfNotExist'
是模板:
<xsl:template name="nIfNotExist" xmlns:scom="http://www.mycomapny.com/s/schema">
<xsl:param name="nodeToTest"/>
<xsl:param name="nodeName"/>
...
我希望生成的文档的根元素如下所示:
<r xmlns:s="http://www.mycompany.com/s/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/default/schema">
我希望"http://www.mycompany.com/default/schema"
作为默认命名空间,以便文档可以通过XSD验证。否则,我必须在运行验证之前手动添加它(不是批处理的选项)。
修改
我试过这个:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="http://www.mycompany.com/schema"
xmlns="http://www.mycompany.com/def_schema">
结果是没有数据的文档,如下所示:
<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema">
<a></a>
<s:b></s:b>
<c></c>
....
应该是:
<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema">
<a>123</a>
<s:b>ABC34L</s:b>
<c>7.092381</c>
更新
源数据看起来像这样(我得到的输入中没有定义名称空间):
<ROOT_NODE>
<DATA_A>1234</DATA_A>
<DATA_B>34567</DATA_B>
<OTHER_DATA_C>7.123456</OTHER_DATA_C>
</ROOT_NODE>
期望的输出
<r xmlns:s="http://www.mycompany.com/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mycompany.com/def_schema">
<a>1234</a>
<s:b>34567</s:b>
<c>7.123456</c>
</r>
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:s="http://www.mycompany.com/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mycompany.com/def_schema"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<r>
<xsl:apply-templates/>
</r>
</xsl:template>
<xsl:template match="DATA_A">
<a>
<xsl:apply-templates/>
</a>
</xsl:template>
<xsl:template match="OTHER_DATA_C">
<c>
<xsl:apply-templates/>
</c>
</xsl:template>
<xsl:template match="DATA_B">
<s:b>
<xsl:apply-templates/>
</s:b>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<ROOT_NODE>
<DATA_A>1234</DATA_A>
<DATA_B>34567</DATA_B>
<OTHER_DATA_C>7.123456</OTHER_DATA_C>
</ROOT_NODE>
产生想要的结果:
<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema">
<a>1234</a>
<s:b>34567</s:b>
<c>7.123456</c>
</r>
答案 1 :(得分:0)
你已经到了正确答案的一半。当您在转换的根处声明默认命名空间时,您断言(假设您不在其他地方覆盖声明)该文档中的所有非限定元素都属于该命名空间。转换发出的每个非限定元素都属于该命名空间。你有那个部分。
我认为您可能忽略的是,XSLT转换中的命名空间声明也适用于转换中的XPath模式。我敢打赌,你的转换中的XPath节点测试不匹配任何输入节点,因为输入节点在空命名空间中,而不是你在转换中声明的命名空间。
你可能想要做的是这样的事情:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="http://www.mycompany.com/schema"
xnlns:no=""
xmlns="http://www.mycompany.com/def_schema">
...然后相应地更改变换中的模式:
<xsl:template match="no:foo">
<foo>...</foo>
</xsl:template>
顺便说一句,这是xsl:element
存在的原因之一 - 您可以构建一个模板,用以将元素从一个名称空间转换为另一个名称空间,例如:
<xsl:template match="no:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:element>
修改强>
之前我没有以这种方式玩过命名空间,事实证明上述内容实际上并不合法。您不能使用名称空间前缀指定任何名称空间。所以你不能使用目标命名空间作为转换的默认命名空间,因为那时你无法告诉XPath在源文档中找到元素。
您可以使用前缀指定输出命名空间,例如:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s="http://www.mycompany.com/schema"
xmlns:out="http://www.mycompany.com/def_schema">
...但是这会将 out
命名空间前缀写入输出,这不会打扰任何XML处理器,但可能会打扰人类。或者您可以在模板中明确指定它,例如:
<xsl:template match="foo">
<xsl:element name="foo" namespace="http://www.mycompany.com/def_schema">
...
</xsl:element>
</xsl:template>
答案 2 :(得分:0)
有许多可能的解决方案,但似乎没有一个在PL / SQL中在Oracle中运行良好。其中一个开发人员通过将XML对象转换为CLOB,执行一些字符串操作以将默认命名空间强制转换为根元素,然后转换回XML以进行下一步,从而“解决”了这一点...我不知道喜欢它,但它有效...