2010-09-17 48 views
-1

我有一个SQL表名为CasingRules XML列,其中将包含诸如数据来创建子节点:使用XPath/XQuery的在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> 

我试图使用MS SQL的修改方法添加新节点“ApplyTo”到每一个项目,打造类似:

<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> 

..但我非常新手与XPath,甚至不会知道它可以更新多个节点一个查询?有没有一种优雅的方式来实现这一目标?

我期待的语法是这样的,但它不工作:

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

回答

0

不是很确定的XQuery MSSQL中的支持可以处理这个问题,但如果有人知道更好,会很乐意听到别的(并转换接受的答案)。

所以在此期间,我在C#中,而不是更新时间:

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

这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(/*) 

输出:

<?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

看起来不错,但我努力形成的XQuery到一个更新语句,我可以与MSSQL-2005中使用。我开始认为MSSQL中的XQuery支持可能不会达到此目的。 – PaulG 2010-09-17 20:36:56

+0

@PaulG:我很遗憾听到......我回答只是因为我看到了'xquery'标签。 – 2010-09-17 21:08:38