2012-09-10 78 views
0

我正在运行一个转换过程来更新我们的一些xml文件。下面是一个示例文件:XPATH查询结果不一致

<?xml version="1.0" encoding="utf-8"?> 
<Jobs xmlns="urn:mynamespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Job name="Job1"> 
    <Category>Maintenance</Category> 
    <Description>Purge records</Description> 
    <Steps> 
     <TSql name="Start Job" database="IADS"> 
     <CommandText>Exec StoredProcedureName</CommandText> 
     <OnSuccess action="GotoNextStep" /> 
     <Retries>0</Retries> 
     <OnFailure action="QuitFailure" /> 
     <OutputFile /> 
     </TSql> 
     <TSql name="Start LoadRequestManagementReportTables" database="msdb"> 
     <CommandText>exec sp_start_job @job_name = 'Load Request Management Report Tables'</CommandText> 
     <OnSuccess action="QuitSuccess" /> 
     <Retries waitInMinutes="0">0</Retries> 
     <OnFailure action="QuitFailure" /> 
     <OutputFile /> 
     </TSql> 
    </Steps> 
    <Schedules> 
     <Schedule> 
     <Weekly name="Every Sunday at 7:00 AM" enabled="false"> 
      <BeginDate>2008-11-01</BeginDate> 
      <RunTimes> 
      <Once>07:00</Once> 
      </RunTimes> 
      <DaysOfWeek>Sunday</DaysOfWeek> 
     </Weekly> 
     </Schedule> 
     <Schedule> 
     <OneTime name="OneTime" enabled="false" rundate="2011-01-12T03:00:00" /> 
     </Schedule> 
    </Schedules> 
    <Notifications> 
     <EventLog on="Failure" /> 
    </Notifications> 
    </Job> 
</Jobs> 

现在,我想重命名每一个我处理,将其从一个TSQL一步一个的CmdExec步转换的文件的第一个步骤。因此,我编写了自己的“RenameNode”方法来执行此转换,并将所有属性和节点复制到新命名节点。

这里的RenameNode方法:

private static void RenameNode(XmlNode node, string namespaceURI, string newName) 
{ 
    if (node.NodeType != XmlNodeType.Element) 
     return; 

    XmlElement oldElement = (XmlElement)node; 
    XmlElement newElement = node.OwnerDocument.CreateElement(newName, namespaceURI); 

    while (oldElement.HasAttributes) 
     newElement.SetAttributeNode(oldElement.RemoveAttributeNode(oldElement.Attributes[0])); 

    while (oldElement.HasChildNodes) 
     newElement.AppendChild(oldElement.FirstChild); 

    if (oldElement.ParentNode != null) 
     oldElement.ParentNode.ReplaceChild(newElement, oldElement); 
} 

我遇到的问题是,我运行第二个查询不返回结果。

这里的查询#1,我跑:

XmlNodeList stepNodes = xSchedule.SelectNodes("/mns:Jobs/mns:Job/mns:Steps/mns:TSql", nsm); 

这个伟大的工程,在我的stepNodes变量返回的2个节点。我处理stepNodes [0]的“RenameNode”方法。太棒了。

我想要做的下一件事是删除“RenameNode”方法生成的命名空间属性(我猜你们不会这样做......但这不是问题)。所以,为了做到这一点,我尝试运行一个非常相似的XPath查询,看起来像这样,但它不返回任何记录:

stepNodes = xSchedule.SelectNodes("/mns:Jobs/mns:Job/mns:Steps/mns:CmdExec", nsm); 

我试图重新命名空间管理,我已经试过节能xml文件(xSchedule.Save()),尝试运行带或不带名称空间前缀/参数的查询等。它从不返回任何节点。即使在对节点进行重命名后,在保存文档后,我可以看到它已成功重命名了该节点(并因此将xmlns属性添加到了该新命名节点中的所有内容中)。我甚至证实,返回结果的原始查询现在只返回1个节点。

// Let's assume that the very first node is the node that we want to change 
     XmlNodeList stepNodes = xSchedule.SelectNodes("/mvst:Jobs/mvst:Job/mvst:Steps/mvst:TSql", nsm); 
    if (stepNodes.Count >= 1) 
    { 
     RenameNode(stepNodes[0], String.Empty, "CmdExec"); 

     // After renaming the node, let's remove the "database" attribute if it exists 
     //XmlElement e = (XmlElement)stepNodes[0]; 
     //e.RemoveAttribute("database"); 
     xSchedule.Save(scheduleXmlFile + ".bak"); 
    } 

我在哪里出错了这段代码?

+1

中间XML是怎么样的,或者如何改变节点? – Lucero

+0

呃。你提示我看看我的“RenameNode”方法,并且我注意到我通过显式地将名称空间定义为String.Empty而不是实际值来调用方法。切换固定我的查询。如果有人很好奇,我会用重命名方法更新原始问题.... – ganders

+0

那么,你可能会发现问题。 ;) – Lucero

回答

0

只需要将名称空间信息传递给RenameNode方法。

RenameNode(stepNodes[0], "urn:mynamespace", "CmdExec");