Управление именами пространства имен атрибута XElement

Я нахожусь в процессе создания механизма экспорта, который будет принимать данные нашей компании и экспортировать их в формате XML на основе шаблона, представленного в нашей базе данных. В одном из экспортов, которые мне нужно реализовать, должен быть добавлен атрибут xsi:nil="true" к элементу, когда значение элемента равно нулю.

Я перебираю каждый элемент в списке экспорта, генерирую его внутренние объекты XElement (в соответствии с нашими правилами) и сохраняю представление.ToString() в базе данных. После генерации всех внутренних частей они извлекаются из базы данных, анализируются обратно в объекты XElement и добавляются во внешний корень XML. (Наличие всего этого в базе данных позволяет приостановить экспорт, возобновить экспорт после перезапуска сервера и т. Д.)

Я указал пространство имен xsi во внешнем корне, однако это не работает при добавлении (анализируемого) внутреннего XElement.

Это представление о том, как работает мой код:

//Generate inner xml
XElement innerElement = new XElement("inner");
XNamespace xsi = @"http://www.w3.org/2001/XMLSchema-instance";
XAttribute attrib = new XAttribute(xsi + "nil", "true");
innerElement.Add(attrib);

//Mock out saving XElement as string
string innerString = innerElement.ToString();
XElement innerElementParsed = XElement.Parse(innerString);

//Add innerxml to outer xml root
XNamespace outerXsi = "http://www.w3.org/2001/XMLSchema-instance";
XAttribute outerAttrib = new XAttribute(XNamespace.Xmlns + "xsi", outerXsi);
XElement outerElement = new XElement("Outer", outerAttrib);
outerElement.Add(innerElementParsed);
return outerElement.ToString();

Я получаю следующие результаты

<Outer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <inner p1:nil="true" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance" />
</Outer>

Я не могу понять, как не использовать расширенные имена (в нижней части этой страницы: http://msdn.microsoft.com/en-us/library/system.xml.linq.xnamespace.aspx)

Если бы мне удалось удалить шаг ".ToString()", сохранив его в базе данных посередине, у меня не было бы этой проблемы, потому что добавление всех элементов XElement напрямую разрешало пространства имен правильно.

Итак, мой вопрос: есть ли способ контролировать синтаксический анализ, чтобы он не использовал расширенное имя p1 и вместо этого использовал пространство имен внешнего XElement? ИЛИ Есть ли что-то, что будет смотреть на Расширенное имя и видеть, что оно совпадает с корневым, и, следовательно, удалять его?

1 ответ

Решение

Чтобы решить эту проблему, мы в итоге добавили "внешний" XElement (с объявленными соответствующими пространствами имен) вокруг каждого из результатов перед выполнением.ToString() и сохранением их в базе данных. Затем, когда мы извлекаем результаты XML-элемента из базы данных и анализируем его обратно в XElement, мы смотрим на свойство.Elements() этого XElement и извлекаем его в наш больший "конечный" объект XElement вместо самого анализируемого XElement.

Другие вопросы по тегам