2017-09-14 3 views
1

En U-SQL, j'essaie d'obtenir une liste d'éléments à l'intérieur des éléments, en utilisant le XmlExtractor. Mais je ne peux pas obtenir la collection imbriquée.U-SQL avec XmlExtractor - éléments à l'intérieur des éléments

Il s'agit d'une liste d'éléments ayant des emplacements. Avec le XmlExtractor je peux obtenir une collection d'éléments, mais je ne vois pas comment je peux obtenir une collection qui contient une collection. Un exemple XML est illustré ci-dessous.

Des idées?

<root> 
<Item> 
    <Header> 
     <id>111</id> 
    </Header> 
    <Body> 
     <Locations> 
      <Location> 
       <Station>k4</Station> 
       <Timestamp>2017-08-30T02:04:18.2506945+02:00</Timestamp> 
      </Location> 
      <Location> 
       <Station>k5</Station> 
       <Timestamp>2017-08-30T02:04:18.2506945+02:00</Timestamp> 
      </Location> 
     </Locations> 
    </Body> 
</Item> 
<Item> 
    <Header> 
     <id>222</id> 
    </Header> 
    <Body> 
     <Locations> 
      <Location> 
       <Station>k4</Station> 
       <Timestamp>2017-08-30T02:12:36.1218601+02:00</Timestamp> 
      </Location> 
      <Location> 
       <Station>k5</Station> 
       <Timestamp>2017-08-30T02:12:36.1218601+02:00</Timestamp> 
      </Location> 
     </Locations> 
    </Body> 
</Item> 
</root> 
+0

Pouvez-vous confirmer ce que vos résultats attendus ressemblent? – wBob

Répondre

1

résolu en faisant un extracteur qui prend le XML dans une chaîne, puis appelle une méthode utilisant XPath, renvoyant un SQL.Array, où la chaîne a des valeurs séparées par des virgules du résultat. Le résultat ressemble à ceci:

111;k4,2017-08-30T02:04:18.2506945+02:00 
111;k5,2017-08-30T02:04:18.2506945+02:00 
222;k4,2017-08-30T02:12:36.1218601+02:00 
222;k5,2017-08-30T02:12:36.1218601+02:00 

Le XmlExtractor standard ne peut pas le faire, et j'ai aussi décidé qu'il est préférable de reporter l'analyse syntaxique du XML après qu'il a été extrait, car il peut y avoir plusieurs étapes sur la même xml.

1

La base de données SQL Azure dispose de puissantes capacités de déchiquetage XML. Peut-être que si cela est déjà dans votre domaine/architecture, il pourrait faire une alternative simple au code personnalisé? Un exemple simple:

DECLARE @xml XML = '<root> 
<Item> 
    <Header> 
     <id>111</id> 
    </Header> 
    <Body> 
     <Locations> 
      <Location> 
       <Station>k4</Station> 
       <Timestamp>2017-08-30T02:04:18.2506945+02:00</Timestamp> 
      </Location> 
      <Location> 
       <Station>k5</Station> 
       <Timestamp>2017-08-30T02:04:18.2506945+02:00</Timestamp> 
      </Location> 
     </Locations> 
    </Body> 
</Item> 
<Item> 
    <Header> 
     <id>222</id> 
    </Header> 
    <Body> 
     <Locations> 
      <Location> 
       <Station>k4</Station> 
       <Timestamp>2017-08-30T02:12:36.1218601+02:00</Timestamp> 
      </Location> 
      <Location> 
       <Station>k5</Station> 
       <Timestamp>2017-08-30T02:12:36.1218601+02:00</Timestamp> 
      </Location> 
     </Locations> 
    </Body> 
</Item> 
</root>' 


/* 
111;k4,2017-08-30T02:04:18.2506945+02:00 
111;k5,2017-08-30T02:04:18.2506945+02:00 
222;k4,2017-08-30T02:12:36.1218601+02:00 
222;k5,2017-08-30T02:12:36.1218601+02:00 
*/ 

SELECT 
    r.c.value('(Header/id/text())[1]', 'int') id, 
    b.c.value('(Station/text())[1]', 'varchar(10)') station, 
    b.c.value('(Timestamp/text())[1]', 'varchar(40)') [timestamp], 
    b.c.value('(Timestamp/text())[1]', 'datetimeoffset') [timestamp2] 
FROM @xml.nodes('root/Item') r(c) 
    CROSS APPLY r.c.nodes('Body/Locations/Location') b(c) 

Vous pouvez faire quelque chose de similaire si le XML est également stocké dans une table.

Mes résultats: My results