0

私は現在、XML ドキュメントからすべての名前空間を取り除き、それらをヘッダーに再度追加するように設計されたバグのあるコードに取り組んでいます。これを使用するのは、非常に大きな xml ドキュメントを取り込み、それらを小さなフラグメントで再提供するためです。そのため、各アイテムは親ドキュメントの名前空間を複製する必要があります。

XML は最初に XmlDocument として読み込まれ、次に名前空間を削除する関数に渡されます。

        _fullXml = new XmlDocument();
        _fullXml.LoadXml(itemXml);
        RemoveNamespaceAttributes(_fullXml.DocumentElement);

remove 関数は、ドキュメント全体を繰り返し処理して名前空間を探し、それらを削除します。次のようになります。

    private void RemoveNamespaceAttributes(XmlNode node){

        if (node.Attributes != null)
        {
            for (int i = node.Attributes.Count - 1; i >= 0; i--)
            {
                if (node.Attributes[i].Name.Contains(':') || node.Attributes[i].Name == "xmlns")
                    node.Attributes.Remove(node.Attributes[i]);
            }
        }

        foreach (XmlNode n in node.ChildNodes)
        {
            RemoveNamespaceAttributes(n);
        }
    }

しかし、それが機能しないことがわかりました。すべての名前空間がそのまま残ります。

デバッガーを使用してコードを反復処理すると、想定どおりに動作しているように見えます。ノード オブジェクトの名前空間属性が削除されています。ただし、元の _fullXml ドキュメントは変更されません。これは、関数が元のデータではなく、渡されたデータのクローンを見ているためだと思います。

だから私の最初の考えは、それをrefで渡すことでした。しかし、foreach ループ内の関数の反復部分にコンパイル エラーがあるため、それはできません。オブジェクト n を参照渡しすることはできません。

2 番目に考えたのは、_fullXml ドキュメント全体を渡すことでしたが、それはまだクローンであるため、推測しても機能しません。

そのため、ドキュメントを ref で渡し、ノードを反復処理してすべての名前空間を削除するという問題を解決する必要があるようです。これには、明らかにこのコード フラグメントを再設計する必要がありますが、それを行う良い方法がわかりません。誰でも助けることができますか?

乾杯、マット

4

2 に答える 2

0

これで失敗したケースがないかどうかは100%わかりませんが、私にはあなたができることが起こります

string x = Regex.Replace(xml, @"(xmlns:?|xsi:?)(.*?)=""(.*?)""", "");

名前空間を取り除くために生のxmlで。

これを解決するのはおそらく最善の方法ではありませんが、私はそれをそこに出すと思いました。

于 2012-04-17T23:55:27.810 に答える
0

名前空間を削除するには、次のようにします。

void StripNamespaces(XElement input, XElement output)
{
    foreach (XElement child in input.Elements())
    {
        XElement clone = new XElement(child.Name.LocalName);
        output.Add(clone);
        StripNamespaces(child, clone);
    }
    foreach (XAttribute attr in input.Attributes())
    {
        try
        {
            output.Add(new XAttribute(attr.Name.LocalName, attr.Value));
        }
        catch (Exception e)
        {
            // Decide how to handle duplicate attributes
            //if(e.Message.StartsWith("Duplicate attribute"))
            //output.Add(new XAttribute(attr.Name.LocalName, attr.Value));
        }
    }
}

次のように呼び出すことができます。

XElement result = new XElement("root");
StripNamespaces(NamespaceXml, result);
于 2012-04-17T23:29:57.940 に答える