2012-05-12 66 views
5

Mam program w języku C# do generowania pliku RDL Do wyświetlania raportu w usługach raportowania. Używam Linq do Xml do generowania Xml.Dodanie atrybutu xmlns do elementu głównego

Kiedy próbuję dodać xmlns XAttribute do elementu raportu, napotykam kilka problemów.

przetestować następujące metody:

pierwsze:

 XDocument d = new XDocument(
      new XDeclaration("1.0", "utf-8", "yes"), 
      new XElement("Report", 
       new XAttribute(XNamespace.Xmlns + "rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"), 
       new XAttribute(XNamespace.Xmlns + "cl", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition"), 
       new XAttribute("xmlns", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"), 
        new XElement("DataSources", ""), 
        new XElement("DataSets", ""), 
        new XElement("ReportSections", 

jest to część mojego kodu czarownice pokazują jak wygenerowania xml:

drugie:

XNamespace reportDef = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"; 
     XDocument d = new XDocument(
      new XDeclaration("1.0", "utf-8", "yes"), 
      new XElement(reportDef + "Report", 
       new XAttribute(XNamespace.Xmlns + "rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"), 
       new XAttribute(XNamespace.Xmlns + "cl", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition"), 
        new XElement("DataSources", ""), 
        new XElement("DataSets", ""), 
        new XElement("ReportSections",... 

Pierwsza metoda zwraca błąd, a druga metoda dodaje atrybut xmlns do wszystkich węzłów podrzędnych.

chcę tego formatu:

<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"> 

Odpowiedz

4

Spróbuj dodać Ci węzły potomne za pomocą XNamespace jak opisano w How to: Create a Document with Namespaces (C#) (LINQ to XML)

XNamespace reportDef = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"; 
XElement root = new XElement(reportDef + "Report", 
    new XElement(reportDef + "Child", "child content")); 

To powinno dać pożądanego rezultatu.

Można również dodać domyślnej przestrzeni nazw dodając atrybut

XElement xe = new XElement(reportDef + "Report", 
    new XAttribute("xmlns", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"), 
    new XElement(reportDef + "Child", "child content")); 
+1

używam tego rozwiązania, ale niestety jak wcześniej ten atrybut dodać do wszystkich węzłów potomnych. –

+0

Wydaje się dziwne, ponieważ nie mogę tego odtworzyć.Spróbuj dodać domyślny atrybut przestrzeni nazw, tak jak w moim drugim przykładzie. Może zaktualizuj pytanie i pokaż więcej swojego rzeczywistego kodu. – Filburt

+0

Niestety tak jak przed –

2

Widać z @ odpowiedź Filburt i this postu xmlns, że atrybut xmlns jest specjalnym atrybutem. Dostęp do niego można uzyskać tylko za pośrednictwem klasy XNamespace.

Poniżej podam przykład jak tworzyć przestrzenie nazw. Aby uzyskać więcej informacji, zajrzyj na stronę How to: Create a Document with Namespaces. Powodem, dla którego twój kod dodaje znaczniki xmlns do wszystkich dzieci, jest to, że nie tworzysz wszystkich węzłów potomnych w tej samej przestrzeni nazw.

  1. Aby umieścić elementy w domyślnej przestrzeni nazw, należy utworzyć (NS1 patrz poniżej) XNamespace i poprzedzić wartości do nazwy pierwiastka. Przykład: new XElement(ns1 + "Report"); Powoduje to utworzenie elementu <Report> w przestrzeni nazw ns1 i nie ma przedrostka.
  2. Aby dodać dodatkowe przestrzenie nazw, dodaj atrybut z przestrzenią nazw i prefiksem. Na przykład new XAttribute(XNamespace.Xmlns + "ns2", ns2) dodaje obszar nazw do elementu <Report> z prefiksem ns2. Następnie za każdym razem, gdy utworzysz element (new XElement(ns2+"DataSources")) z przestrzenią nazw ns2, użyty zostanie prefiks. Prefiks może być użyty we wszystkich potomkach pod elementem z deklaracją prefiksu. Tutaj popełniłeś błąd.

    StringBuilder sb = new StringBuilder(); 
        XmlWriterSettings xws = new XmlWriterSettings(); 
        xws.OmitXmlDeclaration = true; 
        xws.Indent = true; 
    
        using (XmlWriter xw = XmlWriter.Create(sb, xws)) 
        { 
         XNamespace ns1 = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"; 
         XNamespace ns2 = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"; 
         XNamespace ns3 = "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition"; 
         XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes")); 
         XElement reportElement = new XElement(ns1 + "Report", 
          new XAttribute(XNamespace.Xmlns + "ns2", ns2), 
          new XAttribute(XNamespace.Xmlns + "ns3", ns3)); 
         doc.Add(reportElement); 
    
         reportElement.Add(new XElement(ns2+"DataSources")); 
         reportElement.Add(new XElement(ns3+"DataSets")); 
         reportElement.Add(new XElement(ns1+"ReportSections")); 
    
         doc.WriteTo(xw); 
        } 
    
        System.Diagnostics.Debug.Write(sb.ToString()); 
    
+0

Tak, wszystkie węzły potomne tworzą w ten sam sposób. Edytuję pierwszy i drugi przykładowy kod. proszę sprawdź to. dzięki –

+0

@AmirReza Dodałem przykład i odnotowałem twój błąd. Zasadniczo trzeba było umieścić 'nowy XElement (reportDef +" DataSources "," ")' zamiast 'new XElement (" DataSources "," ")'. Przestrzeń nazw była niedostępna dla dzieci, więc skończyły w pustym obszarze nazw. – user845279

Powiązane problemy