我不确定它是否重要,但我正在使用BizTalk 2009来生成XML。
有没有办法在我的XML架构中指定生成的XML实例应该使用目标命名空间作为默认命名空间?
如果我有这样的xsd文件:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/">
<xs:element name="example">
<xs:complexType>
<xs:attribute name="value" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:schema>
它创建一个这样的XML文件:
<ns0:example value="something" xmlns:ns0="http://example.com/" />
但我希望它能像这样创建一个XML文件:
<example value="something" xmlns="http://example.com/" />
我知道它们在技术上是等价的,但消费者(供应商API)的实施很差,我想给他们期望的东西。
答案 0 :(得分:1)
我希望它取决于生成实例的软件,而不是模式。 XSD Schema是为了针对模式验证XML实例而开发的,而不是用于从中生成实例。所以它不太可能在XMLSchema中明确出现。但是,生成工具可能使用元素是(非)限定的事实
elementFormDefault="(un)qualified"
触发前缀。
不完全在范围内,但以下内容值得阅读架构设计:http://www.xfront.com/HideVersusExpose.html
答案 1 :(得分:1)
一种方法是定义没有命名空间的模式。将BizTalk架构映射到没有命名空间的新定义的架构。从BizTalk的角度来看,您将拥有一个表示与消费者的实际合同的模式。 (即没有命名空间)此外,BizTalk使用命名空间#rootnodename来定义messageTypes。在此示例中,您将有两个模式
这种方法的可能缺点是这会将此模式(#rootnodename)的使用限制为使用BizTalk组的1个实例。
答案 2 :(得分:1)
这是BizTalk使用此XML模式的默认行为,据我所知,没有内置方法可以更改它。
然而,您真正想要的是,出站消息符合比BizTalk使用的更清晰,更自由的格式。您可以通过使用自定义管道组件(和自定义发送管道)在传出消息离开BizTalk之前处理它。
我们的想法是更改名称空间前缀,作为在BizTalk外部发送邮件的一部分。转换发生在发送管道的处理过程中。
Nic Barden已发布博客并提供了一些源代码about this here。您可以使用他的示例作为执行名称空间前缀替换的基础,而不是替换名称空间本身。
我强烈建议您查看他在开发流媒体管道组件方面所做的所有帖子。 Nic已经做了大量而全面的工作,描述了编写健壮的企业级管道组件所需的所有内容。
答案 3 :(得分:1)
只要BizTalk btm映射邮件,就会添加ns0
前缀。它不应该重要,因为它仍然是有效的xml,但是当向具有遗留或不完整的xml解析器的合作伙伴发送消息时,这可能是一个问题。
您可以删除ns0
前缀,然后通过更改visual map to an .xslt
map的btm,在输出消息上设置ns0
默认命名空间。
e.g。将地图转换为xslt后,请更改xslt:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl s0"
version="1.0"
xmlns:ns0="http://targetns"
xmlns:s0="http://sourcens"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="/">
<xsl:apply-templates select="s0:FromRoot" />
</xsl:template>
<xsl:template match="s0:FromRoot">
<ns0:ToRoot>
<xsl:for-each select="s0:FromElement">
<ns0:ToElement>
<xsl:value-of select="text()"/>
</ns0:ToElement>
</xsl:for-each>
</ns0:ToRoot>
</xsl:template>
</xsl:stylesheet>
要:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl s0"
version="1.0"
xmlns="http://targetns"
xmlns:s0="http://sourcens"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="/">
<xsl:apply-templates select="s0:FromRoot" />
</xsl:template>
<xsl:template match="s0:FromRoot">
<ToRoot>
<xsl:for-each select="s0:FromElement">
<ToElement>
<xsl:value-of select="text()"/>
</ToElement>
</xsl:for-each>
</ToRoot>
</xsl:template>
</xsl:stylesheet>
即。更改默认的xmlns,然后自动删除ns0前缀。
更通用的解决方案也是可能的(例如类似于Firras'answer here),这可能是有用的,例如作为发送端口映射放置以从元素中去除所有前缀。但是,如果输出消息上有多个xmlns,则需要警惕!