背景:
我們有一個發送埠,使用 XML Transmitt 管道輸出 xml 檔案。
我們有一個發送埠,它使用 XML Transmitt 管道來輸出 xml 檔案。這些檔案的前綴是<ns0:或<ns1:等。 這使得目標系統很難讀取這些檔案,所以我們想用<nl: 替換<ns0: 前綴,用<cbc: 替換<ns1: 前綴,等等。 我們不能改變源模式。我們必須改變從管道輸出的資訊。
我撰寫了一個自定義的 XML 閱讀器,它接收一個包含它應該替換的命名空間的 , 分隔字串,并將它們放入一個 Dictionary。如果一個前綴存在 就會被替換。 用早期輸出的資訊測驗這個閱讀器,得到了預期的結果。但當我試圖將其用于管道時,我遇到了問題。
方法:
- 一個帶有一個管道的管道,它是由一個 "小 "字組成的。
- 一個流水線,在Assemble階段有一個XML-Assembler,在Decode階段的一個組件中有我的自定義閱讀器,我們的想法是將訊息從 XML-Assembler的訊息并對其進行修改。我得到了一個錯誤提示:
"在執行發送管道時出現了故障。 原因是。狀態為EndRootElement的令牌StartElement將導致無效的XML檔案。請確保ConformanceLevel設定是 ConformanceLevel.Fragment或ConformanceLevel.Auto,如果你想寫一個XML片段。
但是我在解碼階段的閱讀器和寫入器都使用ConformanceLevel.Auto,所以我不知道如何解決這個問題。
- 在解碼階段只有我的組件的管道,我認為這應該是可行的。它有點像,但XML看起來有點不同,最大的不同是根元素。 最大的區別是根元素和xmldeclaration不見了。
這里是管道組件的代碼(NamespaceReplacements和OmitXmlDeclaration是屬性):
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
IBaseMessagePart bodyPart = pInMsg.BodyPart。
如果(bodyPart != null)
{
Stream originalStream = bodyPart.GetOriginalDataStream();
如果(originalStream != null)
{
XmlReaderSettings readerSettings = new XmlReaderSettings()。
readerSettings.ConformanceLevel = ConformanceLevel.Auto;
using (XmlReader reader = new XmlChangePrefixReader(XmlReader.Create(originalStream, readerSettings), NamespaceReplacements) )
{
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.ConformanceLevel = ConformanceLevel.Auto;
writerSettings.OmitXmlDeclaration = OmitXmlDeclaration;
MemoryStream outputStream = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(outputStream, writerSettings))
{
reader.Read()。
如果(reader.NodeType == XmlNodeType.XmlDeclaration)
{
writer.WriteStartDocument()。
reader.Read();
}
reader.Read();
while (reader.NodeType == XmlNodeType.Element)
{
writer.WriteNode(reader, true)。
}
}
outputStream.Position = 0;
bodyPart.Data = outputStream;
}
}
}
return pInMsg;
}
而這里是讀者的代碼:
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Generic;
using System.Xml;
public class XmlChangePrefixReader : XmlReader
{
private XmlReader _wrappedReader;
private Dictionary<string, string> _prefixReplacements;
//私有以隱藏默認建構式
私有XmlChangePrefixReader()
{ }
/// <summary>
/// Ctor
/// </summary> //// Ctor
/// <param name="wrappedReader"/span>> 內部xmlreader</param>
/// <param name="prefixReplacements">要被替換的前綴為一個Ⅳ級分隔字串。例如 "A;B;C;D "將用B替換A,用D替換C。</param>
public XmlChangePrefixReader(XmlReader wrappedReader, string prefixReplacements)
{
Initialise(wrappedReader,prefixReplacements)。
}
#region Untouched overrides
public override int AttributeCount { get { return _wrappedReader.AttributeCount; } }
public override string BaseURI { get { return _wrappedReader.BaseURI; } }
public override void Close() { _wrappedReader.Close(); }
public override int Depth { get { return _wrappedReader.Depth; } }
public override bool EOF { get { return _wrappedReader.EOF; } }
public override string GetAttribute(int i) { return _wrappedReader.GetAttribute(i); }
public override string GetAttribute(string name, string namespaceURI) { return _wrappedReader.GetAttribute(name, namespaceURI); }
public override string GetAttribute(string name) { return GetAttribute(name); }
public override bool HasValue { get { return _wrappedReader.HasValue; } }
公共覆寫 bool IsEmptyElement { get { return _wrappedReader.IsEmptyElement; } }
public override string LookupNamespace(string prefix) { return _wrappedReader.LookupNamespace(prefix); }
public override bool MoveToAttribute(string name, string ns) { return _wrappedReader.MoveToAttribute(name, ns); }
public override bool MoveToAttribute(string name) { return _wrappedReader.MoveToAttribute(name); }
public override bool MoveToElement() { return _wrappedReader.MoveToElement(); }
public override bool MoveToFirstAttribute() { return _wrappedReader.MoveToFirstAttribute(); }
public override bool MoveToNextAttribute() { return _wrappedReader.MoveToNextAttribute(); }
public override XmlNameTable NameTable { get { return _wrappedReader.NameTable; } }
public override string NamespaceURI { get { return _wrappedReader.NamespaceURI; } }
public override XmlNodeType NodeType { get { return _wrappedReader.NodeType; } }
public override bool Read() { return _wrappedReader.Read(); }
public override bool ReadAttributeValue() { return _wrappedReader.ReadAttributeValue(); }
public override ReadState ReadState { get { return _wrappedReader.ReadState; } }
public override void ResolveEntity() { _wrappedReader.ResolveEntity(); }
public override string Value { get { return _wrappedReader.Value; } }
#endregion
/// <summary>
/// 如果localname包含一個應該被改變的前綴,則改變它。
/// </summary>
公共凌駕字串LocalName
{
得到
{
如果(_prefixReplacements.ContainsKey(_wrappedReader.LocalName))
return _prefixReplacements[_wrappedReader.LocalName];
否則
回傳_wrappedReader.LocalName。
}
}
/// <summary>
/// 改變前綴,如果它是一個應該被改變的前綴
/// </summary>
公共凌駕字串Prefix
{
得到
{
如果(_prefixReplacements.ContainsKey(_wrappedReader.Prefix))
return _prefixReplacements[_wrappedReader.Prefix];
否則
回傳_wrappedReader.Prefix。
}
}
/// <summary>
/// 初始化
/// </summary> //// Initialize
/// <param name="wrappedReader"/span>> 內部xmlreader</param>
/// <param name="prefixReplacements"/span>> 要替換的前綴</param>
private void Initialise(XmlReader wrappedReader, string prefixReplacements)
{
如果(wrappedReader == null)
拋出新的ArgumentNullException("XmlChangePrefixReader:wrappedReader為空")。
_wrappedReader = wrappedReader。
_prefixReplacements = new Dictionary<string, string>();
如果(prefixReplacements != null)
{
var prefixArray = prefixReplacements.Split(',');
for (int i = 0; i < prefixArray.Length; i = i 2)
{
_prefixReplacements.Add(prefixArray[i], prefixArray[i 1])。
}
}
}
}
對于我如何讓approac 1或2發揮作用,有什么建議嗎?或者我應該嘗試其他方法?
uj5u.com熱心網友回復:
僅僅是命名空間前綴是不重要的
。你的努力被證明是困難的,因為你的目標被誤導了。 僅僅是命名空間前綴是無足輕重的。 只有通過它們與命名空間值的系結,命名空間前綴才會產生意義。
在這個基礎上,你試圖把命名空間前綴當作除了與命名空間值的系結之外的真正意義。 它們并不重要。 因此,你不可能輕松地與那些正確地將命名空間前綴單獨視為無關緊要的符合標準的庫進行斗爭。
那些得到這個訊息的人通常會有兩種反應: 憤怒地,因為他們只是想要一個快速的解決方案來消除他們所認為的繼承問題。
快樂地,因為他們只想快速解決他們所認為的遺傳問題。
高興地,因為他們現在覺得有理由修復潛在的問題,或者將客戶/顧客/老板/同事指向一個來源,證實是下游系統在要求特定命名空間前綴方面出現了問題。
強烈推薦#2。修復根本問題--不要通過黑客來延續它。 #2 強烈建議:修復根本問題--不要通過黑客來延續它。
uj5u.com熱心網友回復: 這里有一個通用的XSLT,用于從XML中移除命名空間。
XSLT
標籤: 下一篇:將區域變數改為全域變數不起作用
還請參見
。
<?xml version="1.0"? >
<xsl:styleheet version="1. 0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl: output method="xml"/span> indent="yes" omit-xml-declaration="yes"/>
<!--模板復制元素-->
<xsl:template match="*"/span>>
<xsl:element name="{local-name()}"/span>>
<xsl:apply-templates select="@* | node()"/span>/>
</xsl: element>
</xsl:template>
<!--模板復制屬性-->
<xsl:template match="@*"/span>>
<xsl:attributee name="{local-name()}"/span>>
<xsl:value-of select="."/span>/>
</xsl: attribute>
</xsl:模板>
<!--模板復制其余節點-->
<xsl:template match="comment() | text() | processing-instruction() ">
<xsl:copy/gt;
</xsl:template>/span>
</xsl:styleheet>/span>
