使用XSLT转换序列化的.net对象

时间:2012-11-12 07:53:14

标签: c# xml xslt serialization datacontractserializer

我有一个很大的.net类和一些xslt文件。我正在将我的对象序列化以使用我的xslt文件进行转换。

我的班级名称是应用程序,它有一个申请人属性,其中包含一组应用程序。

public class Application
{
    public Person Applicant { get; set; }
}

public class Person
{
    public List<Application> Applications { get; set; }
}

当我序列化我的类的一个实例时,通常我获得的Xml包含 z:Ref =“i18”属性,以防止无限的Xml创建来描述现有的引用属性。但是这种情况会改变我必须在Xslt文件中写入所需的Xpath表达式。

我是否有机会序列化包含真实实体值的对象,而不是指定深度的 z:Ref 标记?

这是我的序列化代码:

public string Serialize(object input)
{
    XmlDocument XmlDoc = new XmlDocument();
    DataContractSerializer xmlDataContractSerializer = 
        new DataContractSerializer(input.GetType());
    MemoryStream MemStream = new MemoryStream();
    try
    {
        xmlDataContractSerializer.WriteObject(MemStream, input);
        MemStream.Position = 0;
        XmlDoc.Load(MemStream);
        return XmlDoc.InnerXml;
    }
    finally
    {
        MemStream.Close();
    }
}

提前致谢,

Anıl

2 个答案:

答案 0 :(得分:2)

不,基本上。但是,您应该能够使用以下内容:

<xsl:key name="ids" match="*[@z:Id]" use="@z:Id"/>

然后使用xsl key函数传递当前节点的@z:Ref,其中zxmlns的{​​{1}}别名 - 将在至少保持使用相同。


完整示例 - xslt first(“my.xslt”):

http://schemas.microsoft.com/2003/10/Serialization/

请注意,它通过<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:dcs="http://schemas.datacontract.org/2004/07/" > <xsl:key name="ids" match="*[@z:Id]" use="@z:Id"/> <xsl:output method="xml" indent="yes"/> <xsl:template match="*[@z:Ref]"> <xsl:param name="depth" select="5"/> <xsl:apply-templates select="key('ids', @z:Ref)"> <xsl:with-param name="depth" select="$depth"/> </xsl:apply-templates> </xsl:template> <xsl:template match="*[@z:Id]"> <xsl:param name="depth" select="5"/> <xsl:value-of select="$depth"/>: <xsl:value-of select="name()"/><xsl:text xml:space="preserve"> </xsl:text> <xsl:if test="$depth > 0"> <xsl:apply-templates select="dcs:*"> <xsl:with-param name="depth" select="($depth)-1"/> </xsl:apply-templates> </xsl:if> </xsl:template> </xsl:stylesheet> 参数(递减)遍历5个级别;关键部分是任何元素$depth上的初始match,然后使用*[@z:Ref]代理对原始元素的相同请求,通过key解析。这意味着当我们转向子元素时,我们只需要使用类似的东西:

@z:Id

虽然我们显然可以更精细,例如:

<xsl:apply-templates select="dcs:*"/>

另请注意,要添加<xsl:apply-templates select="dcs:Foo"/> 特定的Foo,您需要添加:

match

确保我们的<xsl:template match="dcs:Foo[@z:Id]"><!-- --></xsl:template> 匹配继续处理引用转发。

和C#:

*[@z:Ref]

答案 1 :(得分:0)

尝试使用XmlSerializer

TestClass TestObj = new TestClass();
XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass));
TextWriter WriteFileStream = new StreamWriter(@"C:\test.xml");
SerializerObj.Serialize(WriteFileStream, TestObj);
WriteFileStream.Close();

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx