2010-06-08 8 views
35

J'ai le code XML suivant que je suis en train d'interroger avec XDocument:XDocument contenant namespaces

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"> 
    <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system"> 
     <EventID>589828</EventID> 
     <Type>3</Type> 
     <SubType Name="Information">0</SubType> 
     <Level>8</Level> 
     <TimeCreated SystemTime="2010-06-01T09:45:15.8102117Z" /> 
     <Source Name="System.ServiceModel" /> 
     <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> 
     <Execution ProcessName="w3wp" ProcessID="5012" ThreadID="5" /> 
     <Channel /> 
     <Computer>TESTSERVER3A</Computer> 
    </System> 
    <ApplicationData> 
     <TraceData> 
      <DataItem> 
       <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Information"> 
        <TraceIdentifier>http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Activation.WebHostCompilation.aspx</TraceIdentifier> 
        <Description>Webhost compilation</Description> 
        <AppDomain>/LM/W3SVC/257188508/Root-1-129198591101343437</AppDomain> 
        <Source>System.ServiceModel.Activation.ServiceParser/39498779</Source> 
        <ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/StringTraceRecord"> 
         <VirtualPath>/Service.svc</VirtualPath> 
        </ExtendedData> 
       </TraceRecord> 
      </DataItem> 
     </TraceData> 
    </ApplicationData> 
</E2ETraceEvent> 

exécution du code suivant renvoie null pour XEL1 sauf quand je supprimer manuellement les espaces de noms:

XDocument xDoc = XDocument.Parse(CurrentString); 
XElement xEl1 = xDoc.Element("E2ETraceEvent"); 
XElement xEl2 = xEl1.Element("System"); 
XElement xEl3 = xEl2.Element("Correlation"); 
XAttribute xAtt1 = xEl3.Attribute("ActivityID"); 
String sValue = xAtt1.Value; 

Comment écrire du code pour extraire le Guid dans XDocument?

Répondre

51

Essayez cela, fonctionne pour moi

XNamespace nsSys = "http://schemas.microsoft.com/2004/06/windows/eventlog/system"; 
    XElement xEl2 = xDoc.Element(nsSys + "System"); 
    XElement xEl3 = xEl2.Element(nsSys + "Correlation"); 
    XAttribute xAtt1 = xEl3.Attribute("ActivityID"); 
    String sValue = xAtt1.Value; 

Vous devez utiliser Namespaces.

source complet pour le procès

 public static void Main() 
     { 
      XElement xDoc = XElement.Parse(
      @"<E2ETraceEvent xmlns=""http://schemas.microsoft.com/2004/06/E2ETraceEvent""> 
    <System xmlns=""http://schemas.microsoft.com/2004/06/windows/eventlog/system""> 
     <EventID>589828</EventID> 
     <Type>3</Type> 
     <SubType Name=""Information"">0</SubType> 
     <Level>8</Level> 
     <TimeCreated SystemTime=""2010-06-01T09:45:15.8102117Z"" /> 
     <Source Name=""System.ServiceModel"" /> 
     <Correlation ActivityID=""{00000000-0000-0000-0000-000000000000}"" /> 
     <Execution ProcessName=""w3wp"" ProcessID=""5012"" ThreadID=""5"" /> 
     <Channel /> 
     <Computer>TESTSERVER3A</Computer> 
    </System> 
    <ApplicationData> 
     <TraceData> 
      <DataItem> 
       <TraceRecord xmlns=""http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"" Severity=""Information""> 
        <TraceIdentifier>http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Activation.WebHostCompilation.aspx</TraceIdentifier> 
        <Description>Webhost compilation</Description> 
        <AppDomain>/LM/W3SVC/257188508/Root-1-129198591101343437</AppDomain> 
        <Source>System.ServiceModel.Activation.ServiceParser/39498779</Source> 
        <ExtendedData xmlns=""http://schemas.microsoft.com/2006/08/ServiceModel/StringTraceRecord""> 
         <VirtualPath>/Service.svc</VirtualPath> 
        </ExtendedData> 
       </TraceRecord> 
      </DataItem> 
     </TraceData> 
    </ApplicationData> 
</E2ETraceEvent>"); 

      XNamespace nsSys = "http://schemas.microsoft.com/2004/06/windows/eventlog/system"; 
      XElement xEl2 = xDoc.Element(nsSys + "System"); 
      XElement xEl3 = xEl2.Element(nsSys + "Correlation"); 
      XAttribute xAtt1 = xEl3.Attribute("ActivityID"); 
      String sValue = xAtt1.Value; 

      Console.WriteLine("sValue = {0}", sValue); 

      Console.ReadKey(); 
     } 
+0

L'espace de noms est la clé – ChrisP

+14

Ça n'avait aucun sens pour moi jusqu'à ce que je réalise qu'ils remplaçaient l'opérateur + pour 'XNamespace' et 'string'. Yucky yucky yuck. –

+3

Si vous souhaitez éviter la surcharge de l'opérateur "+", vous pouvez créer le XName explicitement à partir d'un nom local et un espace de noms comme ceci: 'XName.Get (" System ", nsSys.NamespaceName)' – Coruscate5

1

Utilisez les objets XNamespace dans votre requête pour les balises "xmnls =" données dans les éléments que vous souhaitez interroger. Je n'ai pas testé, mais quelque chose comme cela devrait fonctionner

XNamespace eventSpace = "http://schemas.microsoft.com/2004/06/E2ETraceEvent"; 
XNamespace systemSpace = "http://schemas.microsoft.com/2004/06/windows/eventlog/system"; 

XElement eventElement = document.Element(eventSpace + "E2ETraceEvent"); 
XElement systemElement = eventElement.Element(systemSpace + "System"); 
20

Anthony est adressé le bit d'espace de nom - et XAttribute a une conversion explicite à GUID, donc cela devrait fonctionner:

XNamespace eventNs = "http://schemas.microsoft.com/2004/06/E2ETraceEvent"; 
XNamespace systemNs = "http://schemas.microsoft.com/2004/06/windows/eventlog/system"; 

Guid guid = (Guid) document.Element(eventNs + "E2ETraceEvent") 
          .Element(systemNs + "System") 
          .Element(systemNs + "Correlation") 
          .Attribute("ActivityID"); 

Notez comment les espaces de noms sont pas hérité pour les attributs. L'utilisation d'une seule instruction comme je l'ai fait ici peut parfois simplifier la vie, mais rend le débogage plus difficile car vous ne voyez pas les valeurs intermédiaires. Modifier selon les goûts :)

+0

Je pense que vous voulez dire implicite conversion d'opérateur? :) –

+3

@MarkS: Non, je veux dire explicite. Voir http://msdn.microsoft.com/en-us/library/bb301657(v=vs.110).aspx –