簡體   English   中英

如何修復XML中缺少的名稱空間前綴

[英]How to fix missing namespace prefix in XML

我有一個XML文件,我自己無法修改。 它包含以下根元素:

<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" noNamespaceSchemaLocation="some.xsd">

如您所見, noNamespaceSchemaLocation缺少前綴xsi: noNamespaceSchemaLocation 這會導致XmlReader在驗證時找不到架構信息。 如果添加前綴,一切都很好。 但是正如我所說,我不能修改XML文件(除了測試)。 我從外部來源獲得它們,我的工具應自動驗證它們。

是否可以使XmlReader解釋沒有xsi:前綴的noNamespaceSchemaLocation 我不想在預處理步驟或類似的步驟中在XML內添加前綴,因為源應該完全保持原樣。

XML錯誤,您需要對其進行修復。 要么讓您的供應商提高其發送質量,要么在到達時對其進行維修。

我不知道您為什么要保留損壞的源(所有質量標准都說這是不好的做法),但是保留損壞的原始版本和修復版本當然是可能的。

XmlReader的內部結構很丑陋 沒有文檔說明 因此,此解決方案就像玩火。

我建議的是:一個“添加”缺少的名稱空間的XmlTextReader 您可以將此FixingXmlTextReader直接FixingXmlTextReaderXDocument.Load()也可以將其提供給XmlTextReader / XmlValidatingReader (它們都具有接受XmlReader作為參數的構造函數/ Create )。

public class FixingXmlTextReader : XmlTextReader
{
    public override string NamespaceURI
    {
        get
        {
            if (NodeType == XmlNodeType.Attribute && base.LocalName == "noNamespaceSchemaLocation")
            {
                return NameTable.Add("http://www.w3.org/2001/XMLSchema-instance");
            }

            return base.NamespaceURI;
        }
    }

    public override string Prefix
    {
        get
        {
            if (NodeType == XmlNodeType.Attribute && base.NamespaceURI == string.Empty && base.LocalName == "noNamespaceSchemaLocation")
            {
                return NameTable.Add("xsi");
            }

            return base.Prefix;
        }
    }

    public override string Name
    {
        get
        {
            if (NodeType == XmlNodeType.Attribute && base.NamespaceURI == string.Empty && base.LocalName == "noNamespaceSchemaLocation")
            {
                return NameTable.Add(Prefix + ":" + LocalName);
            }

            return base.Name;
        }
    }

    public override string GetAttribute(string localName, string namespaceURI)
    {
        if (localName == "noNamespaceSchemaLocation" && namespaceURI == "http://www.w3.org/2001/XMLSchema-instance")
        {
            namespaceURI = string.Empty;
        }

        return base.GetAttribute(localName, namespaceURI);
    }

    public override string GetAttribute(string name)
    {
        if (name == "xsi:noNamespaceSchemaLocation")
        {
            name = "noNamespaceSchemaLocation";
        }

        return base.GetAttribute(name);
    }

    // There are tons of constructors, take the ones you need
    public FixingXmlTextReader(Stream stream) : base(stream)
    {
    }

    public FixingXmlTextReader(TextReader input) : base(input)
    {
    }

    public FixingXmlTextReader(string url) : base(url)
    {
    }
}

喜歡:

using (var reader = new FixingXmlTextReader("XMLFile1.xml"))
using (var reader2 = XmlReader.Create(reader, new XmlReaderSettings
{
}))
{
    // Use the reader2!
}

要么

using (var reader = new FixingXmlTextReader("XMLFile1.xml"))
{
    var xdoc = new XmlDocument();
    xdoc.Load(reader);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM