いくつかの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);
}
私が抱えている問題は、実行する2番目のクエリが結果を返さないことです。
これが私が実行するクエリ#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())を保存したり、名前空間プレフィックス/パラメーターを使用した場合と使用しない場合でクエリを実行したりしました。ノードが返されることはありません。ノードの名前を変更した後でも、ドキュメントを保存した後、そのノードの名前が正常に変更されたことがわかります(したがって、その新しく名前が付けられたノードのEVERYTHINGに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");
}
このコードのどこが間違っているのですか?