Add namespace and alias to existing xml

2019-08-20 20:32发布

问题:

I am using the code below to change a namespace in an existing XML message in a BizTalk pipeline component. This works but how would I add a namespace alias to the document as well.

XNamespace toNs = "http://hl7.org/fhir/Encounters";

XElement doc = XElement.Parse(xmlIn);

doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();

var ele = doc.DescendantsAndSelf();

foreach (var el in ele)
    el.Name = toNs +  el.Name.LocalName;

return new XDocument(doc);

回答1:

You can simply add a declaration attribute to the root. Take this example:

<Root>
    <Child>Value</Child>
</Root>

If you run this code:

var root = XElement.Parse(xml);

XNamespace ns = "http://www.example.com/";

foreach (var element in root.DescendantsAndSelf())
{
    element.Name = ns + element.Name.LocalName;
}

root.Add(new XAttribute(XNamespace.Xmlns + "ex", ns));

You'll get this result:

<ex:Root xmlns:ex="http://www.example.com/">
  <ex:Child>Value</ex:Child>
</ex:Root>

See this fiddle for a demo.



回答2:

Now that we know the reason for this (duplicate MessageTypes), the correct BizTalk way to handle this is to deploy Custom Pipelines with configured XmlDisassembler components. Everyone should be doing this anyway.

Please refer to this TechNet Wiki Article which describes this exact scenario and how to resolve it: BizTalk: Improve Deployment and Tracking by Always Creating Custom Pipelines

If you absolutely must modify the content, the correct way in a Pipeline Component is to use the XmlTranslatorStream. This is instead of XmlDocument or XDocument.

From a BizTalk perspective, the marked Answer is not correct. Sorry. :(