.Net XML序列化数组中包含带有xmlns的元素,并且后续的XSLT转换失败

时间:2011-12-29 16:20:00

标签: xml xslt xml-serialization transform xml-namespaces

我有一个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 =“对象的命名空间”属性:

    <?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>

这会导致转换失败。我尝试了一些设置命名空间的东西(可能不是正确的方法)。我找到解决问题的唯一方法是在序列化之后在数据的innerXml上运行一个正则表达式,然后在转换之前删除所有出现的有问题的xmlns属性(感谢Ultrapico的expresso使这很容易做到这些天):

/// <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 :(得分:0)

您可能只需要在样式表中注册每个名称空间。您可以在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表达式并匹配样式表中的模式,以便它们使用这些前缀。