2010-09-17 4 views
-1

J'ai une table SQL avec une colonne XML nommé CasingRules, qui contiendrait des données telles que:Utilisation de XPath/XQuery pour créer des nœuds enfants dans une colonne SQL

<root> 
    <Item> 
    <RegularExpression>^Mc[A-Z,a-z]*</RegularExpression> 
    <Format>ULU</Format> 
    </Item> 
    <Item> 
    <RegularExpression>^Mac[A-Z,a-z]*</RegularExpression> 
    <Format>ULLU</Format> 
    </Item> 
</root> 

J'essaie d'utiliser MS SQL Modifions méthode pour ajouter un nouveau noeud « ApplyTo » dans chaque élément, pour créer quelque chose comme:

<root> 
    <Item> 
    <RegularExpression>^Mc[A-Z,a-z]*</RegularExpression> 
    <Format>ULU</Format> 
    <ApplyTo>NameAndAddress</ApplyTo> 
    </Item> 
    <Item> 
    <RegularExpression>^Mac[A-Z,a-z]*</RegularExpression> 
    <Format>ULLU</Format> 
    <ApplyTo>NameAndAddress</ApplyTo> 
    </Item> 
</root> 

.. mais je suis très bien un débutant à XPath, et même pas sûr s'il est possible de mettre à jour plusieurs noeuds une requête? Y a-t-il un moyen élégant d'y parvenir?

J'attends la syntaxe est quelque chose comme ça, mais ce ne fonctionne pas:

UPDATE TableName 
SET CasingRules.modify('insert <ApplyTo>NameAndAddress</ApplyTo> as last into (/root//Item[1])') 

Répondre

0

Pas si sûr XQuery le support dans MSSQL peut gérer ceci, mais sera heureux d'entendre autrement (et changer la réponse acceptée) si quelqu'un sait mieux.

Alors en attendant, je mis à jour en C# à la place:

foreach (TypedRow row in typedDataSet) 
{ 
    XmlDocument casingRulesXml = new XmlDocument(); 
    casingRulesXml.LoadXml(row.CasingRules); 

    if (casingRulesXml.GetElementsByTagName("ApplyTo").Count == 0) 
    { 
    XmlNodeList itemNodes = casingRulesXml.GetElementsByTagName("Item"); 

    for (int i = 0; i < itemNodes.Count; i++) 
    { 
     XmlElement newElement = casingRulesXml.CreateElement("ApplyTo"); 
     newElement.InnerText = "NameAndAddress"; 
     itemNodes[i].AppendChild(newElement); 
    } 

    // In this case the xml has no heading declaration. 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.OmitXmlDeclaration = true; 
    settings.ConformanceLevel = ConformanceLevel.Fragment; 

    StringBuilder stringBuilder = new StringBuilder(); 
    XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings); 
    casingRulesXml.WriteTo(xmlWriter); 
    xmlWriter.Flush(); 

    row.CasingRules = stringBuilder.ToString(); 
    } 
} 
0

Ce XQuery:

declare namespace local = "http://example.org"; 
declare function local:copy($element as element()) { 
    element {node-name($element)} 
    {$element/@*, 
    for $child in $element/node() 
     return if ($child instance of element()) 
      then local:test($child) 
      else $child 
    } 
}; 
declare function local:test($element as element()) { 
    local:copy($element), 
    for $true in ($element[parent::Item][not(following-sibling::*)]) 
    return <ApplyTo>NameAndAddress</ApplyTo> 
}; 
local:copy(/*) 

Sortie:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <Item> 
    <RegularExpression>^Mc[A-Z,a-z]*</RegularExpression> 
    <Format>ULU</Format> 
    <ApplyTo>NameAndAddress</ApplyTo> 
    </Item> 
    <Item> 
    <RegularExpression>^Mac[A-Z,a-z]*</RegularExpression> 
    <Format>ULLU</Format> 
    <ApplyTo>NameAndAddress</ApplyTo> 
    </Item> 
</root> 
+0

semble bon, mais je me bats pour former cette XQuery dans une déclaration de mise à jour que je peux utiliser avec MSSQL-2005. Je commence à penser que le support de XQuery dans MSSQL n'est peut-être pas à la hauteur. – PaulG

+0

@PaulG: Je suis désolé d'entendre ça ... J'ai répondu juste parce que j'ai vu la balise 'xquery'. –

Questions connexes