我有一个非常大的xml文件,其中包含一些我感兴趣的信息,但我需要以另一种方式呈现它。让我来说明一下:
SOURCE XML
<root attribute1="something" attribute2="somethingelse">
<items>
<item id="dontcare" name="Need This Name 1" url="http://NeedThisUrl1.com">
<availability>
<instores/>
</availability>
</item>
<item id="dontcare" name="Need This Name 2" url="http://NeedThisUrl2.com">
<availability>
<instores/>
</availability>
</item>
</items>
</root>
结果XML
<Items>
<Item Attribute1="HardcodedValue1" Attribute2="HardcodedValue2">
<Parameter Name="Id">Hardcoded Value</Parameter>
<Parameter Name="Name">Need This Name 1</Parameter>
<Parameter Name="Url">http://NeedThisUrl1.com</Parameter>
<Parameter Name="Availability">Hardcoded Value</Parameter>
</Item>
<Item Attribute1="HardcodedValue1" Attribute2="HardcodedValue2">
<Parameter Name="Id">Hardcoded Value</Parameter>
<Parameter Name="Name">Need This Name 2</Parameter>
<Parameter Name="Url">http://NeedThisUrl2.com</Parameter>
<Parameter Name="Availability">Hardcoded Value</Parameter>
</Item>
</Items>
如何在C#中实现这一目标?
答案 0 :(得分:3)
您可以尝试XSLT。以下是一些例子:
Converting XML file to another XML file using XSLT
XML to XML with XSLT omitting specific elements based on value
这是一个关于如何使用C#来实现这个目标的例子:
How to apply an XSLT Stylesheet in C#
希望它有所帮助。
答案 1 :(得分:2)
您可以使用C#内置的Xml类来处理它。 Linq也会提供帮助。
以下是有关如何获取值的代码。您可以使用linq来扩展它,因为我将在下面解释中间级别(但上面的示例不需要它,因为不需要第三级)。
internal static LoadIndividualItem(XElement xelement)
{
XElement element = ; //you need to pass the document as an Xelement somehow
foreach (XElement child in element.Elements())
{
string elementName = child.Name.ToString();
if (string.Compare(elementName, "item", true) == 0)
{
string name = child.Attribute(XName.Get("name"));
// Do something with this string
string name = child.Attribute(XName.Get("url"));
// Do something with this string\
}
}
}
以下是如何获取XElement的示例。
public void LoadFromFile(string sourcXmlFileName = null)
{
// Checks to see if file has been specified, if not assign it to the default value
if (string.IsNullOrEmpty(sourceXmdlFileName))
sourceXmdlFileName = DefaultInventoryFile;
// Check to make sure the file is there
if (!File.Exists(sourceXmdlFileName))
return;
List<ObjectToHoldValues> MasterObject = new List<ObjectToHoldValues>();
using (TextReader reader = new StreamReader(sourceXmlFileName, Encoding.UTF8))
{
// Create an xml document and assign it to a local variable
XDocument doc = XDocument.Load(reader);
// Load the roots
foreach (XElement element in doc.Descendants("root"))
{
ObjectToHoldValues itemList = new ObjectToHoldValues();
itemList = LoadIndividualItem(element);
MasterObject.Add(itemList);
}
}
}
您将需要从根开始创建不同的控制器,并使用linq向下移动每个对象,在标记内添加不同的元素。底层标签可能看起来像这样。
internal static LowLevelItem LowLevelFromXml(XElement element)
{
return (
// Create the Inventory item node
new XElement("BottomLevel",
// Create each child node of the values you need
new XElement("ValueOne", _valueOne.ToString())
,new XElement("ValueTwo", _valueTwo));
}
中级对象可能看起来像这样
internal static MidLevelItem MidLevelItemFromXml(XElement element)
{
XElement Root = new XElement("MidLevel");
//Add all of the individual lower level records to the this root
Root.Add(_lowerLevelItems
.Select(item => item.LowLevelFromXml())
.ToArray());
return Root;
}
顶级可能如下所示
public void Save(string targetXmlFileName = null)
{
XDocument doc = new XDocument();
XElement root = new XElement("TopLevel");
//Add the root to the XML document
doc.Add(root);
//Add all of the subitems records to the XML document
root.Add(_midLevelItem
.Select(item => item.MidLevelItemFromXml())
.ToArray());
var settings = new XmlWriterSettings()
{
CloseOutput = true,
Indent = true,
Encoding = Encoding.UTF8
};
// Write the XML file
using (XmlWriter writer = XmlWriter.Create(targetXmlFileName ?? DefaultFile, settings))
{
doc.Save(writer);
}
}
答案 2 :(得分:0)
这只是序列化和反序列化以及修改对象。
我要做的是使用XSD生成两个XML的c#类。然后创建一个方法将每个项目转换为另一个类型。然后,您可以反序列化输入xml,使用新方法,然后序列化新对象。
答案 3 :(得分:0)
假设我们有一个如下所示的XSLT文件,它将用于格式化XML文档,
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo='http://www.w3.org/1999/XSL/Format'
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@`enter code here`* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/ReportTable">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="all-pages" page-width="8.27in" page-height="11.69in">
<fo:region-body region-name="xsl-region-body" margin-left="0.7in" margin-right="0.7in" margin-top="0.7in" margin-bottom="0.7in" column-gap="0.25in" />
<fo:region-before region-name="xsl-region-before" extent="0.7in" display-align="after" padding-left="0.7in" padding-right="0.7in" margin-top="0.2in" margin-bottom="0.4in"/>
<fo:region-after region-name="xsl-region-after" extent="0.7in" padding-left="0.7in" padding-right="0.7in" margin-top="0.2in" margin-bottom="0.1in"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="default-sequence">
<fo:repeatable-page-master-reference master-reference="all-pages" />
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="default-sequence">
<fo:static-content flow-name="xsl-region-before" >
<fo:block text-align="center" font-weight="bold" text-decoration="underline" line-height="200%">Page Title</fo:block>
<fo:block line-height="70%" >
 
</fo:block>
<fo:block line-height="200%">
<!--to increase height between line and Header -->
<fo:table border-collapse="collapse" width="100%" table-layout="fixed">
<fo:table-column column-width="proportional-column-width(15.0)" column-number="1"/>
<fo:table-column column-width="proportional-column-width(45.0)" column-number="2"/>
<fo:table-column column-width="proportional-column-width(25.0)" column-number="3"/>
<fo:table-column column-width="proportional-column-width(15.0)" column-number="4"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell >
<fo:block text-align="center">
<fo:inline font-weight="bold" text-align="center">
<xsl:value-of select="Node1"></xsl:value-of>
</fo:inline>
</fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block text-align="left">
<fo:inline text-align="left">
<xsl:value-of select="Node2"></xsl:value-of>
</fo:inline>
</fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block text-align="right">
<fo:inline font-weight="bold" text-align="right">
<xsl:value-of select="Node3"></xsl:value-of>
</fo:inline>
</fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block text-align="left">
<fo:inline text-align="left">
<xsl:value-of select="Node4"></xsl:value-of>
</fo:inline>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table> 
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after" >
<fo:block line-height="200%">
<!--to increase height between line and footer-->
<fo:table border-collapse="collapse" width="100%" table-layout="fixed" border-top-width="1pt" border-top-style="solid" border-top-color="rgb(0,0,0)">
<fo:table-column column-width="proportional-column-width(50)" column-number="1"/>
<fo:table-column column-width="proportional-column-width(50)" column-number="2"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell >
<fo:block text-align="center">
<fo:inline font-weight="bold" text-align="center">
Page <fo:page-number/> of <fo:page-number-citation ref-id="documentEnd"/>
</fo:inline>
</fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block text-align="right">
<fo:inline font-weight="bold" text-align="right">
<xsl:value-of select="CurrentDate"></xsl:value-of>
</fo:inline>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table> 
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:table border-collapse='collapse' font-size='6pt' font-family='Arial'>
<xsl:apply-templates select='columns'></xsl:apply-templates>
<xsl:apply-templates select='rows'></xsl:apply-templates>
</fo:table>
<fo:block id="documentEnd"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="columns">
<xsl:for-each select="column">
<fo:table-column column-width='80%'/>
</xsl:for-each>
<fo:table-header font-weight='bold' font-size='8pt' line-height="200%" text-align="center" border-top-width="0.5pt" border-top-style="solid" border-top-color="rgb(0,0,0)" border-bottom-width="0.5pt" border-bottom-style="solid" border-bottom-color="rgb(0,0,0)">
<fo:table-row>
<xsl:for-each select="column">
<fo:table-cell padding='2pt'>
<fo:block text-align='center'>
<xsl:value-of select='@colName'/>
</fo:block>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</fo:table-header>
</xsl:template>
</xsl:stylesheet>
在这里使用XDOC,我们创建了一个XML文档,并使用XSLT将此XML转换为另一个XML请遵循以下代码,
string[] ReportTableHeader = { "Headerone", "HeaderTwo", "HeaderTwo"};
XDocument xdoc = new XDocument(new XElement("ReportTable",
new XElement("Node1", headerText1),
new XElement("Node2", headerText2),
new XElement("Node3",headerText3),
new XElement("Node4",headerText4),
new XElement("CurrentDate", footerCurDate),
new XElement("Columns", from col in ReportTableHeader
select
new XElement("Column", new XAttribute("ColName", col.ToString().Trim())))));
XDocument finalXDoc = new XDocument();
using (XmlWriter inputStreamXSLT = finalXDoc.CreateWriter())
{
XslCompiledTransform objXSLT = new XslCompiledTransform();
string xsltFilePath = Server.MapPath(BasePage.GetReportPath(formName));
objXSLT.Load(xsltFilePath);
objXSLT.Transform(xdoc.CreateReader(), inputStreamXSLT);
}
string inputXMLtoXSLT = finalXDoc.ToString();
这里finalDoc是稍后生成的XML Doc,所以我们使用finalDoc.CreateWriter()方法,而xDoc是我们正在读取的xml,所以我们使用xdoc.CreateReader()方法,我们提供了使用Server.MapPath()方法的xslt文件。