0

我正在运行转换过程以更新我们的一些 xml 文件。这是一个示例文件:

<?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");
    }

这段代码我哪里出错了?

4

1 回答 1

0

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

RenameNode(stepNodes[0], "urn:mynamespace", "CmdExec");
于 2012-09-11T17:59:56.140 回答