दिलचस्प पोस्ट
एक स्ट्रिंग में हेरफेर करें जो 30 मिलियन वर्ण लंबा है कोणीय UI- राउटर $ urlRouterProvider। जब काम नहीं कर रहा है * अब * जावा में गतिशील और स्थिर बहुरूपता के बीच अंतर क्या है? साझा किए गए संदर्भ और थ्रेड सुरक्षा आर स्क्रिप्ट से सीधे एक एक्सेल फाइल पढ़ें जबकि ब्लूबर्ड वादों का इस्तेमाल करते हुए लूप कम्पाइलर्स और सी ++ में मूल्यांकन का तर्क क्रम मैं RAILS_ENV को एक रेक कार्य में कैसे लागू कर सकता हूं? जेएस एक खाली वस्तु के बजाय खाली ब्लॉक के रूप में {} व्याख्या करता है? सी # में HTTP POST का उपयोग कर फ़ाइलें भेजना जैक्सन – जेनेरिक क्लास का इस्तेमाल करना JLabel में हाइपरलिंक कैसे जोड़ें दिनांक स्वरूप से दिनांक प्रारूप डीडी / एमएम / य्याय को परिवर्तित करें "संसाधन नहीं मिल सकता है।" त्रुटि जब url के अंत में "डॉट" होती है जावास्क्रिप्ट – एम तत्वों के साथ एन एरेज़ से उत्पन्न संयोजन

XmlSerializer: अनावश्यक xsi और xsd नामस्थानों को हटा दें

क्या XmlSerializer को कॉन्फ़िगर करने का एक तरीका है जिससे कि वह मूल तत्व में डिफ़ॉल्ट नामस्थान नहीं लिखता?

मुझे क्या मिलता है:

<?xml ...> <rootelement xmlns:xsi="..." xmlns:xsd="..."> </rootelement> 

और मैं दोनों xmlns घोषणाओं को निकालना चाहता हूँ।

का डुप्लिकेट : एक्सएमएलएन = "…" प्राप्त किए बिना एक्सएमएल को ऑब्जेक्ट कैसे सीरियल कर सकते हैं?

वेब के समाधान से एकत्रित समाधान "XmlSerializer: अनावश्यक xsi और xsd नामस्थानों को हटा दें"

चूंकि डेव ने मुझे अपने एक्सएसआई और एक्सएसडी नेमस्पेस को एनआईटी में एक सीरियल बनाने के लिए अपने जवाब दोहराने के लिए कहा है, इसलिए मैंने इस पोस्ट को अपडेट किया है और पहले से उल्लेखित लिंक से मेरा जवाब दोहराया है। इस उत्तर में प्रयुक्त उदाहरण दूसरे उदाहरण के लिए इस्तेमाल किया गया एक उदाहरण है। इसके बाद क्या कॉपी किया जाता है, शब्दशः।


माइक्रोसॉफ्ट के प्रलेखन और कई समाधान ऑनलाइन पढ़ने के बाद, मैंने इस समस्या का समाधान खोज लिया है। यह IXmlSerialiazble माध्यम से अंतर्निर्मित XmlSerializer और कस्टम XML धारावाहिक दोनों के साथ काम करता है

कण के लिए, मैं उसी MyTypeWithNamespaces XML नमूना का उपयोग करूँगा जिसका उपयोग इस प्रश्न के उत्तर में अब तक किया गया है।

 [XmlRoot("MyTypeWithNamespaces", Namespace="urn:Abracadabra", IsNullable=false)] public class MyTypeWithNamespaces { // As noted below, per Microsoft's documentation, if the class exposes a public // member of type XmlSerializerNamespaces decorated with the // XmlNamespacesDeclarationAttribute, then the XmlSerializer will utilize those // namespaces during serialization. public MyTypeWithNamespaces( ) { this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { // Don't do this!! Microsoft's documentation explicitly says it's not supported. // It doesn't throw any exceptions, but in my testing, it didn't always work. // new XmlQualifiedName(string.Empty, string.Empty), // And don't do this: // new XmlQualifiedName("", "") // DO THIS: new XmlQualifiedName(string.Empty, "urn:Abracadabra") // Default Namespace // Add any other namespaces, with prefixes, here. }); } // If you have other constructors, make sure to call the default constructor. public MyTypeWithNamespaces(string label, int epoch) : this( ) { this._label = label; this._epoch = epoch; } // An element with a declared namespace different than the namespace // of the enclosing type. [XmlElement(Namespace="urn:Whoohoo")] public string Label { get { return this._label; } set { this._label = value; } } private string _label; // An element whose tag will be the same name as the property name. // Also, this element will inherit the namespace of the enclosing type. public int Epoch { get { return this._epoch; } set { this._epoch = value; } } private int _epoch; // Per Microsoft's documentation, you can add some public member that // returns a XmlSerializerNamespaces object. They use a public field, // but that's sloppy. So I'll use a private backed-field with a public // getter property. Also, per the documentation, for this to work with // the XmlSerializer, decorate it with the XmlNamespaceDeclarations // attribute. [XmlNamespaceDeclarations] public XmlSerializerNamespaces Namespaces { get { return this._namespaces; } } private XmlSerializerNamespaces _namespaces; } 

यह सब इस वर्ग के लिए है अब, कुछ लोग XmlSerializerNamespaces होने का विरोध कर रहे हैं, उनकी कक्षाओं में कहीं न कहीं; लेकिन जैसा कि आप देख सकते हैं, मैंने इसे ठीक से डिफ़ॉल्ट कन्स्ट्रक्टर में टक दिया और नामस्थानों को वापस करने के लिए एक सार्वजनिक संपत्ति का पर्दाफाश किया।

अब, जब यह कक्षा को क्रमबद्ध करने का समय आता है, तो आप निम्न कोड का उपयोग करेंगे:

 MyTypeWithNamespaces myType = new MyTypeWithNamespaces("myLabel", 42); /****** OK, I just figured I could do this to make the code shorter, so I commented out the below and replaced it with what follows: // You have to use this constructor in order for the root element to have the right namespaces. // If you need to do custom serialization of inner objects, you can use a shortened constructor. XmlSerializer xs = new XmlSerializer(typeof(MyTypeWithNamespaces), new XmlAttributeOverrides(), new Type[]{}, new XmlRootAttribute("MyTypeWithNamespaces"), "urn:Abracadabra"); ******/ XmlSerializer xs = new XmlSerializer(typeof(MyTypeWithNamespaces), new XmlRootAttribute("MyTypeWithNamespaces") { Namespace="urn:Abracadabra" }); // I'll use a MemoryStream as my backing store. MemoryStream ms = new MemoryStream(); // This is extra! If you want to change the settings for the XmlSerializer, you have to create // a separate XmlWriterSettings object and use the XmlTextWriter.Create(...) factory method. // So, in this case, I want to omit the XML declaration. XmlWriterSettings xws = new XmlWriterSettings(); xws.OmitXmlDeclaration = true; xws.Encoding = Encoding.UTF8; // This is probably the default // You could use the XmlWriterSetting to set indenting and new line options, but the // XmlTextWriter class has a much easier method to accomplish that. // The factory method returns a XmlWriter, not a XmlTextWriter, so cast it. XmlTextWriter xtw = (XmlTextWriter)XmlTextWriter.Create(ms, xws); // Then we can set our indenting options (this is, of course, optional). xtw.Formatting = Formatting.Indented; // Now serialize our object. xs.Serialize(xtw, myType, myType.Namespaces); 

एक बार जब आप यह कर लेंगे, आपको निम्न आउटपुट प्राप्त करना चाहिए:

 <MyTypeWithNamespaces> <Label xmlns="urn:Whoohoo">myLabel</Label> <Epoch>42</Epoch> </MyTypeWithNamespaces> 

मैंने हाल ही की एक प्रोजेक्ट में इस पद्धति का सफलतापूर्वक उपयोग किया है जिसमें वेब सेवा कॉल के लिए एक्सएमएल को क्रमबद्ध किए जाने वाले कक्षाओं की गहरी हिराचिरी है। माइक्रोसॉफ्ट के प्रलेखन के बारे में बहुत स्पष्ट नहीं है कि सार्वजनिक रूप से एक्सीमेबल XmlSerializerNamespaces सदस्य के साथ क्या करना है एक बार जब आप इसे बनाते हैं, और बहुत से लगता है कि यह बेकार है। लेकिन उनके प्रलेखन का पालन करते हुए और इसे ऊपर दिखाए गए तरीके से उपयोग करके, आप अनुकूलित कर सकते हैं कि एक्सएमएल सेरियलआइज़र अपने वर्गों के लिए असमर्थित व्यवहार के बिना XML के लिए IXmlSerializable को कार्यान्वित करके "अपने खुद के रोलिंग"

यह मेरी आशा है कि यह जवाब आराम करने के लिए, एक बार और सभी के लिए, XmlSerializer द्वारा उत्पन्न मानक xsi और xsd नामस्थानों से छुटकारा पाने के लिए कैसे होगा।

अद्यतनः मैं सिर्फ यह सुनिश्चित करना चाहता हूं कि मैंने सभी नामस्थानों को निकालने के बारे में ओपी के सवाल का उत्तर दिया। उपरोक्त मेरा कोड इसके लिए काम करेगा; मुझे आपको बताने दो कि कैसे। अब, ऊपर दिए गए उदाहरण में, आप वास्तव में सभी नामस्थानों से छुटकारा नहीं पा सकते हैं (क्योंकि उपयोग में दो नामस्थान हैं)। कहीं भी आपके एक्सएमएल दस्तावेज़ में, आपको कुछ एक्सएमएलएन xmlns="urn:Abracadabra" xmlns:w="urn:Whoohoo जैसे कुछ करने की आवश्यकता है। अगर उदाहरण में क्लास एक बड़ा दस्तावेज़ का हिस्सा है, तो कहीं एक नामस्थान के ऊपर या तो दोनों (या दोनों) Abracadbra और Whoohoo लिए घोषित किया जाना चाहिए। यदि नहीं, तो एक या दोनों नामस्थानों में तत्व को किसी प्रकार के उपसर्ग के साथ सजाया जाना चाहिए (आपके दो डिफ़ॉल्ट नामस्थान नहीं हो सकते हैं, है ना?) इसलिए, इस उदाहरण के लिए, Abracadabra डिफ़ॉल्ट नेमस्पेस है। मैं अपने MyTypeWithNamespaces वर्ग के अंदर MyTypeWithNamespaces नाम स्थान के लिए एक नाम स्थान उपसर्ग जोड़ सकता है जैसे:

 public MyTypeWithNamespaces { this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { new XmlQualifiedName(string.Empty, "urn:Abracadabra"), // Default Namespace new XmlQualifiedName("w", "urn:Whoohoo") }); } 

अब, मेरी कक्षा की परिभाषा में, मैंने संकेत दिया कि <Label/> तत्व नामस्थान "urn:Whoohoo" , इसलिए मुझे कुछ और करने की ज़रूरत नहीं है। जब मैं अब अपरिवर्तित उपरोक्त क्रमबद्धता कोड का उपयोग कर वर्ग को सीरियल कर देता हूं, तो यह आउटपुट है:

 <MyTypeWithNamespaces xmlns:w="urn:Whoohoo"> <w:Label>myLabel</w:Label> <Epoch>42</Epoch> </MyTypeWithNamespaces> 

क्योंकि <Label> दस्तावेज़ के बाकी हिस्सों से भिन्न नामस्थान में है, इसलिए इसे किसी स्थान पर, नामस्थान के साथ "सजाया गया" होना चाहिए। ध्यान दें कि अभी भी कोई xsi और xsd नामस्थान नहीं हैं


इससे दूसरे प्रश्न का उत्तर समाप्त होता है I लेकिन मैं यह सुनिश्चित करना चाहता था कि ओ.पी. का कोई नाम स्थान का उपयोग करने के सवाल का उत्तर नहीं दिया, जैसा कि मुझे लगता है कि मैंने वास्तव में इसका अभी तक समाधान नहीं किया है। मान लें कि <Label> एक ही नेमस्पेस का बाकी भाग के रूप में है, इस मामले में urn:Abracadabra :

 <MyTypeWithNamespaces> <Label>myLabel<Label> <Epoch>42</Epoch> </MyTypeWithNamespaces> 

आपका कन्स्ट्रक्टर दिखेगा क्योंकि यह मेरे बहुत पहले कोड उदाहरण में, डिफ़ॉल्ट नामस्थान को प्राप्त करने के लिए सार्वजनिक संपत्ति के साथ होगा:

 // As noted below, per Microsoft's documentation, if the class exposes a public // member of type XmlSerializerNamespaces decorated with the // XmlNamespacesDeclarationAttribute, then the XmlSerializer will utilize those // namespaces during serialization. public MyTypeWithNamespaces( ) { this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { new XmlQualifiedName(string.Empty, "urn:Abracadabra") // Default Namespace }); } [XmlNamespaceDeclarations] public XmlSerializerNamespaces Namespaces { get { return this._namespaces; } } private XmlSerializerNamespaces _namespaces; 

फिर, बाद में, आपके कोड में MyTypeWithNamespaces ऑब्जेक्ट का उपयोग करने के लिए इसे सीरियलाइज करता है, जैसा कि मैंने ऊपर किया था, आप इसे कॉल करेंगे:

 MyTypeWithNamespaces myType = new MyTypeWithNamespaces("myLabel", 42); XmlSerializer xs = new XmlSerializer(typeof(MyTypeWithNamespaces), new XmlRootAttribute("MyTypeWithNamespaces") { Namespace="urn:Abracadabra" }); ... // Above, you'd setup your XmlTextWriter. // Now serialize our object. xs.Serialize(xtw, myType, myType.Namespaces); 

और XmlSerializer आउटपुट में कोई अतिरिक्त नाम स्थान के साथ तुरंत ऊपर दिखाए गए समान एक्सएमएल को वापस थूक नहीं करेगा:

 <MyTypeWithNamespaces> <Label>myLabel<Label> <Epoch>42</Epoch> </MyTypeWithNamespaces> 
 //Create our own namespaces for the output XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); //Add an empty namespace and empty value ns.Add("", ""); //Create the serializer XmlSerializer slz = new XmlSerializer(someType); //Serialize the object with our own namespaces (notice the overload) slz.Serialize(myXmlTextWriter, someObject, ns) 

एक विकल्प है – आप प्रकार के एक सदस्य प्रदान कर सकते हैं XmlSerializer नामस्थानों को क्रमबद्ध करने के लिए प्रकार में इसे XmlNamespaceDeclarations विशेषता के साथ सजाने के लिए उस सदस्य को नामस्थान उपसर्ग और यूआरआई जोड़ें। उसके बाद, कोई भी सीरियललाइजेशन जो स्पष्ट रूप से एक XmlSerializerNamespaces प्रदान नहीं करता है वह नामपेस उपसर्ग + यूआरआई जोड़े जो आप अपने प्रकार में डालते हैं का उपयोग करेंगे।

उदाहरण कोड, मानिए कि यह आपका प्रकार है:

 [XmlRoot(Namespace = "urn:mycompany.2009")] public class Person { [XmlAttribute] public bool Known; [XmlElement] public string Name; [XmlNamespaceDeclarations] public XmlSerializerNamespaces xmlns; } 

तुम यह केर सकते हो:

 var p = new Person { Name = "Charley", Known = false, xmlns = new XmlSerializerNamespaces() } p.xmlns.Add("",""); // default namespace is emoty p.xmlns.Add("c", "urn:mycompany.2009"); 

और इसका मतलब यह होगा कि उस उदाहरण के किसी भी क्रमवारण जो अपने स्वयं के उपसर्ग + यूआरआई जोड़े निर्दिष्ट नहीं करता है, "कलर: mycompany.2009" नाम स्थान के लिए "p" उपसर्ग का उपयोग करेगा। यह भी xsi और xsd नामस्थानों को छोड़ देगा

यहां अंतर यह है कि आप XmlSerializerNamespaces को अपने आप में टाइप कर रहे हैं, बल्कि इसे एक्सएमएल सेरियलाइज़र के लिए कॉल पर स्पष्ट रूप से नियोजित करने के बजाय। इसका मतलब यह है कि यदि आपके प्रकार का एक उदाहरण आपके द्वारा स्वामित्व नहीं किया जाता है, तो कोड के द्वारा आपके द्वारा (जैसा कि एक webservices स्टैक में) सीरियल किया गया है, और वह कोड स्पष्ट रूप से एक XmlSerializerNamespaces प्रदान नहीं करता है, तो वह सीरियलइज़र उदाहरण में दिए गए नामस्थानों का उपयोग करेगा।