.Net XML сериализированный массив содержит элементы с xmlns в них и завершается ошибкой последующего преобразования XSLT - PullRequest
1 голос
/ 29 декабря 2011

У меня есть веб-страница Aspx.Net, которая создает отчет из массива, поступающего через WCF.Массив преобразуется в XML, а затем выполняется через перевод для получения отчета html.

Массив относится к классу, содержащему простые строки и числа.

Я использую процесс сериализации вмассив для создания XML:

XmlDocument xmlData = new XmlDocument();

// serialize the array so we can transform
XmlSerializer slz = new XmlSerializer(typeof (ReportData[]));
using (MemoryStream stream = new MemoryStream())
{
    slz.Serialize(stream, responseMain);
    stream.Position = 0;
    xmlData.Load(stream);
}

Когда генерируется XML, каждый элемент внутри элемента массива содержит атрибут xmlns = "namespace of the object":

    <?xml version="1.0"?>
    <ArrayOfReportData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <GetPaymentOptionReportData>
            <Name xmlns="http://mynamespace.ServiceContracts">SMITH, JAMES E               </Name>
            <IdNumber xmlns="http://mynamespace.ServiceContracts">01081-01        </IdNumber>
            <AcctDate xmlns="http://mynamespace.ServiceContracts">2011-09-19T00:00:00</AcctDate>
            <NumberOfVisits xmlns="http://mynamespace.ServiceContracts">12</NumberOfVisits>
            <Fee xmlns="http://mynamespace.ServiceContracts">329.00</Fee>
        </GetPaymentOptionReportData>
      </ArrayOfReportData>

Это вызываетпреобразование потерпеть неудачу.Я попытался несколько вещей с настройкой пространства имен (вероятно, не правильный путь).Единственный способ решить эту проблему - запустить Regex для innerXml данных после сериализации и перед преобразованием, чтобы удалить все вхождения атрибута xmlns-нарушителей (спасибо Expresso от Ultrapico за простоту выполнения этих операций.дней!):

/// <summary>
///  Regular expression built for C# on: Thu, Dec 29, 2011, 08:14:26 AM
///  Using Expresso Version: 3.0.3634, http://www.ultrapico.com
///  
///  A description of the regular expression:
///  
///  \s?xmlns\s?=\s?"
///      Whitespace, zero or one repetitions
///      xmlns
///      Whitespace, zero or one repetitions
///      =
///      Whitespace, zero or one repetitions
///      "
///  [Protocol]: A named capture group. [\w+]
///      Alphanumeric, one or more repetitions
///  :\/\/
///      :
///      Literal /
///      Literal /
///  [Domain]: A named capture group. [[\w@][\w.:@]+]
///      [\w@][\w.:@]+
///          Any character in this class: [\w@]
///          Any character in this class: [\w.:@], one or more repetitions
///  Literal /, zero or one repetitions
///  Any character in this class: [\w\.?=%&=\-@/$,], any number of repetitions
///  "
///  This regex captures the occurences of 
///
/// </summary>
Regex xmlnsRegex = new Regex(
        "\\s?xmlns\\s?=\\s?\"(?<Protocol>\\w+):\\/\\/(?<Domain>[\\w@]" +
        "[\\w.:@]+)\\/?[\\w\\.?=%&=\\-@/$,]*\"",
     RegexOptions.IgnoreCase
     | RegexOptions.CultureInvariant
     | RegexOptions.IgnorePatternWhitespace
     | RegexOptions.Compiled
     );

// take out namespace attributes inside object elements 
xmlData.InnerXml = xmlnsRegex.Replace(xmlData.InnerXml, "");

Это похоже на клудж, поэтому я надеялся, что какой-нибудь XML-гуру может мне помочь.

1 Ответ

0 голосов
/ 29 декабря 2011

Возможно, вам просто нужно зарегистрировать каждое из этих пространств имен в таблице стилей.Это делается для элемента stylesheet, например:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://mynamespace.ServiceContracts" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

, а затем переписывает выражения XPath и шаблоны соответствия в таблице стилей, чтобы они использовали эти префиксы.

...