[英]Transforming serialized .net object with XSLT
我有一個很大的.net類和一些xslt文件。 我正在將我的對象序列化以使用我的xslt文件進行轉換。
我的類名稱是Application,它有一個Applicant屬性,其中包含一組應用程序。
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();
}
}
提前致謝,
阿尼爾
不,基本上。 但是,您應該能夠使用以下內容:
<xsl:key name="ids" match="*[@z:Id]" use="@z:Id"/>
然后使用xsl key
函數傳遞當前節點的@z:Ref
,其中z
是http://schemas.microsoft.com/2003/10/Serialization/
的xmlns
別名 - 這將至少保持使用整個都一樣。
完整示例 - xslt first(“my.xslt”):
<?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>
注意,這通過$depth
參數(遞減)走5級; 關鍵部分是任何元素*[@z:Ref]
的初始match
,然后使用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>
確保我們的*[@z:Ref]
匹配繼續處理引用轉發。
而C#:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
[DataContract]
public class Foo
{
[DataMember]
public Bar Bar { get; set; }
}
[DataContract]
public class Bar
{
[DataMember]
public Foo Foo { get; set; }
}
static class Program
{
static void Main()
{
var foo = new Foo();
var bar = new Bar();
foo.Bar = bar;
bar.Foo = foo;
using (var ms = new MemoryStream())
{
var ser = new DataContractSerializer(typeof(Foo), new DataContractSerializerSettings {
PreserveObjectReferences = true
});
ser.WriteObject(ms, foo);
Console.WriteLine(Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length));
Console.WriteLine();
ms.Position = 0;
var xslt = new XslCompiledTransform();
xslt.Load("my.xslt");
using (var reader = XmlReader.Create(ms))
{
xslt.Transform(reader, null, Console.Out);
}
}
Console.WriteLine();
Console.WriteLine("press any key");
Console.ReadKey();
}
}
嘗試使用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.