Saya mencari solusi yang bersih, elegan dan cerdas untuk menghapus namespace dari semua elemen XML? Bagaimana fungsinya untuk melakukan itu?
Antarmuka yang ditentukan:
public interface IXMLUtils
{
string RemoveAllNamespaces(string xmlDocument);
}
Contoh XML untuk menghapus NS dari:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<insert>
<offer xmlns="http://schema.peters.com/doc_353/1/Types">0174587</offer>
<type2 xmlns="http://schema.peters.com/doc_353/1/Types">014717</type2>
<supplier xmlns="http://schema.peters.com/doc_353/1/Types">019172</supplier>
<id_frame xmlns="http://schema.peters.com/doc_353/1/Types" />
<type3 xmlns="http://schema.peters.com/doc_353/1/Types">
<type2 />
<main>false</main>
</type3>
<status xmlns="http://schema.peters.com/doc_353/1/Types">Some state</status>
</insert>
</ArrayOfInserts>
Setelah kita memanggil RemoveAllNamespaces (xmlWithLotOfNs), kita harus mendapatkan:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts>
<insert>
<offer >0174587</offer>
<type2 >014717</type2>
<supplier >019172</supplier>
<id_frame />
<type3 >
<type2 />
<main>false</main>
</type3>
<status >Some state</status>
</insert>
</ArrayOfInserts>
Bahasa solusi yang disukai adalah C # pada .NET 3.5 SP1.
Jawaban:
Nah, inilah jawaban akhirnya. Saya telah menggunakan ide Jimmy yang bagus (yang sayangnya tidak lengkap itu sendiri) dan fungsi rekursi lengkap untuk bekerja dengan baik.
Berdasarkan antarmuka:
Saya mewakili di sini solusi C # bersih dan universal akhir untuk menghapus ruang nama XML:
Ini berfungsi 100%, tetapi saya belum banyak mengujinya sehingga mungkin tidak mencakup beberapa kasus khusus ... Tapi itu dasar yang baik untuk memulai.
sumber
Jawaban paling berguna yang diberi tag memiliki dua kekurangan:
Inilah pendapat saya tentang ini:
Kode contoh di sini .
sumber
xmlns
.(from a in e.Attributes().DistinctBy(x => x.Name.LocalName)
untuk kasuslang=""ru-ru"" xml:lang=""ru-ru""
jawaban wajib menggunakan LINQ:
sumber
Itu akan berhasil :-)
sumber
Ambil lagi, di C # - baris ditambahkan untuk menyalin atribut:
sumber
Jawaban wajib menggunakan XSLT:
sumber
Dan ini adalah solusi sempurna yang juga akan menghapus elemen XSI. (Jika Anda menghapus xmlns dan tidak menghapus XSI, .Net berteriak pada Anda ...)
sumber
Regex.Replace(xmlStr, @"<(/?)([^>\s:]+):([^>]+)>", "<$1$3>")
Saya tahu pertanyaan ini seharusnya diselesaikan, tetapi saya tidak sepenuhnya senang dengan cara penerapannya. Saya menemukan sumber lain di sini di blog MSDN yang memiliki
XmlTextWriter
kelas yang diganti yang menghapus ruang nama. Saya sedikit men-tweaknya untuk mendapatkan beberapa hal lain yang saya inginkan seperti pemformatan yang cantik dan mempertahankan elemen root. Inilah yang saya miliki dalam proyek saya saat ini.http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx
Kelas
Pemakaian
sumber
Ini adalah solusi berdasarkan jawaban yang diterima Peter Stegnar.
Saya menggunakannya, tetapi (seperti yang dikatakan andygjp dan John Saunders) kodenya mengabaikan atribut .
Saya perlu menjaga atribut juga, jadi saya menyesuaikan kodenya. Versi Andy adalah Visual Basic, ini masih c #.
Saya tahu ini sudah lama, tetapi mungkin itu akan menghemat waktu seseorang suatu hari nanti.
sumber
Saya sangat menyukai tujuan Dexter di sana, jadi saya menerjemahkannya ke dalam metode ekstensi yang "lancar":
Pendekatan "lancar" memungkinkan saya melakukan ini:
sumber
Anda dapat melakukannya dengan menggunakan LINQ:
sumber
Jawaban Peter yang sedikit dimodifikasi, ini akan berfungsi dengan baik untuk atribut juga, termasuk menghapus namespace dan awalan. Sedikit maaf karena kodenya terlihat agak jelek.
sumber
Balasan oleh Jimmy dan Peter sangat membantu, tetapi mereka benar-benar menghapus semua atribut, jadi saya membuat sedikit modifikasi:
sumber
Agak terlambat ke pesta yang satu ini tapi inilah yang saya gunakan baru-baru ini:
(diambil dari Thread MSDN ini )
Sunting Sesuai komentar di bawah ini, tampaknya sementara ini menghapus awalan namespace dari node itu tidak benar-benar menghapus atribut xmlns. Untuk melakukan itu Anda juga perlu mengatur ulang nama setiap node ke nama lokalnya (misalnya nama minus namespace)
sumber
Agar atribut bekerja, loop for untuk menambahkan atribut harus pergi setelah rekursi, juga perlu memeriksa apakah IsNamespaceDeclaration:
sumber
Ini adalah versi VB.NET saya dari Dexter Legaspi C # Version
sumber
Solusi lain yang memperhitungkan kemungkinan interleaving node TEXT dan ELEMENT, misalnya:
Kode:
sumber
Tanpa menggunakan solusi berbasis XSLT, jika Anda ingin bersih, elegan, dan cerdas, Anda memerlukan dukungan dari kerangka kerja, khususnya, pola pengunjung dapat membuat ini mudah. Sayangnya, tidak tersedia di sini.
Saya telah menerapkannya terinspirasi oleh LINQ
ExpressionVisitor
untuk memiliki struktur yang mirip dengannya. Dengan ini, Anda dapat menerapkan pola pengunjung ke objek XML (LINQ-to-). (Saya telah melakukan pengujian terbatas pada ini tetapi sejauh yang saya tahu berhasil dengan baik)ps, implementasi khusus ini menggunakan beberapa fitur .NET 4 untuk membuat implementasi sedikit lebih mudah / lebih bersih (penggunaan
dynamic
dan argumen default). Seharusnya tidak terlalu sulit untuk membuatnya kompatibel dengan .NET 3.5, bahkan mungkin kompatibel dengan .NET 2.0.Kemudian untuk mengimplementasikan pengunjung, berikut adalah cara umum yang dapat mengubah beberapa ruang nama (dan awalan yang digunakan).
Dan sedikit metode penolong untuk membuat bola bergulir:
Kemudian untuk menghapus namespace, Anda bisa menyebutnya seperti ini:
Menggunakan pengunjung ini, Anda dapat menulis
INamespaceMappingManager
untuk menghapus semua ruang nama.sumber
Solusi sederhana yang benar-benar mengganti nama elemen di tempat, bukan membuat salinan, dan melakukan pekerjaan yang cukup baik dalam mengganti atribut.
Catatan: ini tidak selalu mempertahankan urutan atribut asli, tetapi saya yakin Anda dapat mengubahnya untuk melakukannya dengan mudah jika itu penting bagi Anda.
Perhatikan juga bahwa ini juga dapat memunculkan pengecualian, jika Anda memiliki atribut XElement yang hanya unik dengan namespace, seperti:
yang sepertinya merupakan masalah yang melekat. Tetapi karena pertanyaan menunjukkan mengeluarkan String, bukan XElement, dalam hal ini Anda dapat memiliki solusi yang akan menghasilkan String valid yang merupakan XElement yang tidak valid.
Saya juga menyukai jawaban jocull menggunakan XmlWriter kustom, tetapi ketika saya mencobanya, itu tidak berhasil untuk saya. Meskipun semuanya terlihat benar, saya tidak tahu apakah kelas XmlNoNamespaceWriter berpengaruh sama sekali; itu pasti tidak menghapus ruang nama seperti yang saya inginkan.
sumber
Menambahkan my that juga membersihkan nama node yang memiliki prefiks namespace:
sumber
Saya mencoba beberapa solusi pertama dan tidak berhasil untuk saya. Terutama masalah dengan atribut yang dihapus seperti yang telah disebutkan sebelumnya. Saya akan mengatakan pendekatan saya sangat mirip dengan Jimmy dengan menggunakan konstruktor XElement yang mengambil objek sebagai parameter.
sumber
jawaban saya,
kode berbasis manipulasi string, kode paling ringan,
sumber
Berikut adalah Regex Replace one liner:
Berikut contohnya: https://regex101.com/r/fopydN/6
Peringatan: mungkin ada casing edge!
sumber
Jawaban user892217 hampir benar. Itu tidak akan dikompilasi apa adanya, jadi perlu sedikit koreksi pada panggilan rekursif:
sumber
Ini berhasil untuk saya.
sumber
Setelah banyak mencari solusi untuk masalah ini, halaman khusus ini tampaknya memiliki daging paling banyak ... namun, tidak ada yang benar-benar cocok, jadi saya mengambil cara kuno dan hanya menguraikan hal-hal yang saya inginkan. Semoga ini bisa membantu seseorang. (Catatan: ini juga menghapus SOAP atau barang amplop serupa.)
sumber
Tanpa membuat ulang seluruh hierarki node:
sumber
Saya mencoba beberapa solusi, tetapi seperti yang dinyatakan oleh begitu banyak, ada beberapa kasus tepi.
Menggunakan beberapa regex di atas, tetapi sampai pada kesimpulan bahwa regex satu langkah tidak dapat dibuat.
Jadi inilah solusi saya, 2 langkah regex, temukan tag, di dalam tag hapus, jangan ubah cdata:
Untuk saat ini 100% berhasil untuk saya.
sumber
Berikut adalah solusi berbasis regex untuk masalah ini ...
sumber
Saya pikir ini adalah jawaban terpendek (tetapi untuk konstruksi seperti, Anda akan berdiskusi lagi, saya juga memiliki regex untuk diubah
"<bcm:info></bcm:info>"
menjadi "<info></info>
" tetapi itu tidak dioptimalkan, Jika seseorang bertanya kepada saya, saya akan membagikannya. Jadi, solusi saya adalah:sumber