使用 XML 模式指定 XML 实例中的默认命名空间

发布于 2024-10-10 06:43:05 字数 755 浏览 9 评论 0 原文

我不确定这是否重要,但我正在使用 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)实现得很差,我想要给他们他们所期望的。

I'm not sure if it matters, but I'm using BizTalk 2009 to generate the XML.

Is there a way to specify in my XML schema that the generated XML instance should use the target namespace as the default namespace?

If I have an xsd file like this:

<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>

It creates an XML file like this:

<ns0:example value="something" xmlns:ns0="http://example.com/" />

But I want it to create an XML file like this:

<example value="something" xmlns="http://example.com/" />

I know that they're technically equivalent, but the consumers (vendor APIs) are poorly implemented and I'd like to give them what they expect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

油焖大侠 2024-10-17 06:43:05

我希望它取决于生成实例的软件,而不是模式。 XSD Schema 是为了根据模式验证 XML 实例而开发的,而不是为了从中生成实例。因此它不太可能显式地出现在 XMLSchema 中。然而,生成工具可能利用元素被(不)限定的事实

elementFormDefault="(un)qualified" 

来触发前缀。

不完全在范围内,但以下内容对于模式设计值得阅读: http://www.xfront.com/ HideVersusExpose.html

I would expect that it depends on the software generating the instance, not the schema. XSD Schema was developed for validation of XML instances against a schema, not for generating instances from it. So it is unlikely to be present explicitly in XMLSchema. The generating tools might, however, use the fact that elements were (un)qualified

elementFormDefault="(un)qualified" 

to trigger the prefixing.

Not completely in scope, but the following is worth reading for schema design: http://www.xfront.com/HideVersusExpose.html

苦妄 2024-10-17 06:43:05

一种方法是定义一个没有命名空间的模式。将 BizTalk 架构映射到新定义的架构(不带命名空间)。从 BizTalk 的角度来看,您将拥有一个代表与消费者的实际合同的模式。 (即没有命名空间)此外,BizTalk 使用命名空间#rootnodename 来定义消息类型。在此示例中,您将有两个架构

  1. somenamespace#somerootnodename
  2. #somerootnodename

此方法的可能缺点是,这会将此架构 (#rootnodename) 的使用限制为 BizTalk 组的 1 个实例。

One way would be to define a schema without the namespace. Map the BizTalk schema to the newly defined schema without namespace. From a BizTalk viewpoint, you would have a schema which represents the actual contract with the consumers. (i.e. without namespaces) Also, BizTalk uses namespace#rootnodename to define messageTypes. In this example, you would have two schemas

  1. somenamespace#somerootnodename
  2. #somerootnodename

The possible drawbacks of this approach are this would limiting the usage of this schema (#rootnodename) to 1 instance with the BizTalk group.

晨光如昨 2024-10-17 06:43:05

这是 BizTalk 使用此 XML 架构的默认行为,据我所知,没有内置方法可以更改此行为。

然而,您真正想要的是出站消息符合比 BizTalk 使用的格式更清晰、更自由的格式。您可以通过使用自定义管道组件(和自定义发送管道)在传出消息离开 BizTalk 之前对其进行处理来执行此操作。

这个想法是在 BizTalk 外部发送消息时更改命名空间前缀。转换发生在发送管道的处理期间。

Nic Barden 发表了博客并提供了一些源代码关于此内容 。您可以使用他的示例作为执行命名空间前缀替换的基础,而不是替换命名空间本身。

我强烈建议您查看他撰写的有关开发流管道组件的整个系列文章。 Nic 做了广泛而彻底的工作,描述了编写强大的企业级管道组件所需的所有内容。

This is the default behaviour of BizTalk working this XML schemas and, as far as I know, there is no builtin way to change this.

What you really want, however, is that outbound messages conform to a cleaner and more liberal format than what is used by BizTalk. You can do this by using a custom pipeline component (and a custom send pipeline) to process the outgoing message before it leaves BizTalk.

The idea is to change the namespace prefix as part of sending the message outside BizTalk. The transformation happens during the processing of the send pipeline.

Nic Barden has blogged and provided some source code about this here. You can use his sample as the basis for performing replacement of namespace prefixes, rather than replacing namespaces themselves.

I strongly encourage you to check out the whole series of posts he's done about Developing Streaming Pipeline Components. Nic has made an extensive and thorough job of describing all that's needed to author robust and enterprise-class pipeline components.

尝蛊 2024-10-17 06:43:05

每当 BizTalk btm 映射消息时,都会添加 ns0 前缀。这应该并不重要,因为这仍然是有效的 xml,但是当向使用旧版或不完整 xml 解析器的合作伙伴发送消息时,这可能会出现问题。

您可以删除 ns0 前缀,并将 ns0 作为输出消息上的默认命名空间,方法是从 .xslt 的可视化映射地图

例如,将地图转换为 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 的 在这里回答),这可能很有用,例如放置为发送端口映射以从元素中去除所有前缀。但是,如果输出消息上有多个 xmlns,则需要小心!

The ns0 prefix is added whenever a BizTalk btm maps a message. It shouldn't matter as this is still valid xml, however this could be a problem when sending messages to partners with legacy or incomplete xml parsers.

You can remove the ns0 prefix and instead make ns0 your default namespace on the output message by changing your btm from a visual map to an .xslt map.

e.g. Once you have converted your map to xslt, change the xslt from:

<?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>

To:

<?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>

i.e. change the default xmlns and then remove the ns0 prefixes automatically.

A more generic solution is also possible (e.g. similar to Firras' answer here), which could be useful e.g. to place as a send port map to strip out all prefixes from elements. However, one needs to be wary if there are more than one xmlns on the output message!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文