如何使用 C# 更改 XML 文档中的模式
How to change schemas in an XML document with c#
我有一个 XML 文件,如下所示:
<?xml version="1.0"?>
<paxml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<header>
<format>LÖNIN</format>
<version>2</version>
</header>
<tidtransaktioner>
<tidtrans anstid="1418">
<tidkod>SJK</tidkod>
<datum>2022-02-02T15:20:00</datum>
<timmar>0</timmar>
</tidtrans>
<tidtrans anstid="1418">
<tidkod>SJK</tidkod>
<datum>2022-02-21T10:40:00</datum>
<timmar>0</timmar>
</tidtrans>
</tidtransaktioner>
</paxml>
我需要更改第二行:
<paxml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
变成这样:
<paxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.paxml.se/2.0/paxml.xsd">
有人知道如何做到这一点吗?
这是我的 class XML:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Logic.Shared.Models
{
// using System.Xml.Serialization;
// XmlSerializer serializer = new XmlSerializer(typeof(Paxml));
[XmlRoot(ElementName = "header", Namespace = "")]
public class Header
{
[XmlElement(ElementName = "format", Namespace = "")]
public string Format { get; set; }
[XmlElement(ElementName = "version", Namespace = "")]
public double Version { get; set; }
}
[XmlRoot(ElementName = "dimension", Namespace = "")]
public class Dimension
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "namn", Namespace = "")]
public string Namn { get; set; }
}
[XmlRoot(ElementName = "dimensioner", Namespace = "")]
public class Dimensioner
{
[XmlElement(ElementName = "dimension", Namespace = "")]
public List<Dimension> Dimension { get; set; }
}
[XmlRoot(ElementName = "resultatenhet", Namespace = "")]
public class Resultatenhet
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public int Id { get; set; }
[XmlAttribute(AttributeName = "namn", Namespace = "")]
public int Namn { get; set; }
}
[XmlRoot(ElementName = "resultatenheter", Namespace = "")]
public class Resultatenheter
{
[XmlElement(ElementName = "resultatenhet", Namespace = "")]
public List<Resultatenhet> Resultatenhet { get; set; }
}
[XmlRoot(ElementName = "tidtrans", Namespace = "")]
public class Tidtrans
{
[XmlElement(ElementName = "tidkod", Namespace = "")]
public string Tidkod { get; set; }
[XmlElement(ElementName = "datum", Namespace = "")]
public DateTime Datum { get; set; }
[XmlElement(ElementName = "timmar", Namespace = "")]
public double Timmar { get; set; }
[XmlAttribute(AttributeName = "anstid", Namespace = "")]
public int Anstid { get; set; }
[XmlText]
public string Text { get; set; }
[XmlElement(ElementName = "resenheter", Namespace = "")]
public Resenheter Resenheter { get; set; }
}
[XmlRoot(ElementName = "resenhet", Namespace = "")]
public class Resenhet
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public int Id { get; set; }
}
[XmlRoot(ElementName = "resenheter", Namespace = "")]
public class Resenheter
{
[XmlElement(ElementName = "resenhet", Namespace = "")]
public List<Resenhet> Resenhet { get; set; }
}
[XmlRoot(ElementName = "tidtransaktioner", Namespace = "")]
public class Tidtransaktioner
{
[XmlElement(ElementName = "tidtrans", Namespace = "")]
public List<Tidtrans> Tidtrans { get; set; }
}
[XmlRoot(ElementName = "dag", Namespace = "")]
public class Dag
{
[XmlAttribute(AttributeName = "datum", Namespace = "")]
public DateTime Datum { get; set; }
[XmlAttribute(AttributeName = "timmar", Namespace = "")]
public double Timmar { get; set; }
}
[XmlRoot(ElementName = "schema", Namespace = "")]
public class Schema
{
[XmlElement(ElementName = "dag", Namespace = "")]
public List<Dag> Dag { get; set; }
[XmlAttribute(AttributeName = "anstid", Namespace = "")]
public int Anstid { get; set; }
}
[XmlRoot(ElementName = "schematransaktioner", Namespace = "")]
public class Schematransaktioner
{
[XmlElement(ElementName = "schema", Namespace = "")]
public List<Schema> Schema { get; set; }
}
[XmlRoot(ElementName = "paxml", Namespace = "")]
public class Paxml
{
[XmlElement(ElementName = "header", Namespace = "")]
public Header Header { get; set; }
[XmlElement(ElementName = "dimensioner", Namespace = "")]
public Dimensioner Dimensioner { get; set; }
[XmlElement(ElementName = "resultatenheter", Namespace = "")]
public Resultatenheter Resultatenheter { get; set; }
[XmlElement(ElementName = "tidtransaktioner", Namespace = "")]
public Tidtransaktioner Tidtransaktioner { get; set; }
[XmlElement(ElementName = "schematransaktioner", Namespace = "")]
public Schematransaktioner Schematransaktioner { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = "http://www.paxml.se/2.0/paxml.xsd")]
public string NoNamespaceSchemaLocation { get; set; }
[XmlText]
public string Text { get; set; }
}
}
此 class 是由 XML 文件生成器生成的。如您所见,我一直在尝试添加 XML 属性以手动更改命名空间。
这是逻辑的 class:
using Logic.Mobigo.Services;
using Logic.Shared.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Logic.Services
{
public class XMLService
{
private readonly MobigoTimeService _mobigoTimeService;
private readonly MobigoUserService _mobigoUserService;
public XMLService(MobigoTimeService mobigoTimeService, MobigoUserService mobigoUserService)
{
_mobigoTimeService = mobigoTimeService;
_mobigoUserService = mobigoUserService;
}
public async Task<bool> Xml()
{
var timeRows = await _mobigoTimeService.List();
var xml = new Paxml();
xml.Header = new Header();
xml.Header.Format = "LÖNIN";
xml.Header.Version = 2.0;
var tidTrans = new List<Tidtrans>();
foreach (var timeRow in timeRows)
{
var user = await _mobigoUserService.GetByUserSign(timeRow.UserSign);
;
tidTrans.Add(new Tidtrans
{
Anstid = 1418, //int.Parse(user.EmployeeNr),
Tidkod = "SJK", //timeRow.TimeType.TimeCode,
//hur göra med datum vid månadsöverskridelse????
Datum = timeRow.StopDate,
Timmar = timeRow.TimeAmount,
});
}
xml.Tidtransaktioner = new Tidtransaktioner
{
Tidtrans = tidTrans,
};
var writer = new XmlSerializer(typeof(Paxml));
var path = "C:\Work\Git\LIM\PDF\" + "testfile.xml";
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, xml);
file.Close();
return true;
}
}
}
你离得不远,但你混淆了名称空间和值。您需要名称空间 http://www.w3.org/2001/XMLSchema-instance
中名为 noNamespaceSchemaLocation
且值为 http://www.paxml.se/2.0/paxml.xsd
的属性。看起来像这样:
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string NoNamespaceSchemaLocation { get; set; } = "http://www.paxml.se/2.0/paxml.xsd";
生成的根 XML 默认情况下如下所示:
<paxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="http://www.paxml.se/2.0/paxml.xsd" />
这在语义上与您的要求相同,因此不应导致任何问题。但是如果你真的想要摆脱xsd
的命名空间声明,你可以提供一个XmlSerializerNamespaces
只有你需要的命名空间:
var ns = new XmlSerializerNamespaces();
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
var serializer = new XmlSerializer(typeof(Paxml));
serializer.Serialize(file, xml, ns);
我有一个 XML 文件,如下所示:
<?xml version="1.0"?>
<paxml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<header>
<format>LÖNIN</format>
<version>2</version>
</header>
<tidtransaktioner>
<tidtrans anstid="1418">
<tidkod>SJK</tidkod>
<datum>2022-02-02T15:20:00</datum>
<timmar>0</timmar>
</tidtrans>
<tidtrans anstid="1418">
<tidkod>SJK</tidkod>
<datum>2022-02-21T10:40:00</datum>
<timmar>0</timmar>
</tidtrans>
</tidtransaktioner>
</paxml>
我需要更改第二行:
<paxml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
变成这样:
<paxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.paxml.se/2.0/paxml.xsd">
有人知道如何做到这一点吗?
这是我的 class XML:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Logic.Shared.Models
{
// using System.Xml.Serialization;
// XmlSerializer serializer = new XmlSerializer(typeof(Paxml));
[XmlRoot(ElementName = "header", Namespace = "")]
public class Header
{
[XmlElement(ElementName = "format", Namespace = "")]
public string Format { get; set; }
[XmlElement(ElementName = "version", Namespace = "")]
public double Version { get; set; }
}
[XmlRoot(ElementName = "dimension", Namespace = "")]
public class Dimension
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "namn", Namespace = "")]
public string Namn { get; set; }
}
[XmlRoot(ElementName = "dimensioner", Namespace = "")]
public class Dimensioner
{
[XmlElement(ElementName = "dimension", Namespace = "")]
public List<Dimension> Dimension { get; set; }
}
[XmlRoot(ElementName = "resultatenhet", Namespace = "")]
public class Resultatenhet
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public int Id { get; set; }
[XmlAttribute(AttributeName = "namn", Namespace = "")]
public int Namn { get; set; }
}
[XmlRoot(ElementName = "resultatenheter", Namespace = "")]
public class Resultatenheter
{
[XmlElement(ElementName = "resultatenhet", Namespace = "")]
public List<Resultatenhet> Resultatenhet { get; set; }
}
[XmlRoot(ElementName = "tidtrans", Namespace = "")]
public class Tidtrans
{
[XmlElement(ElementName = "tidkod", Namespace = "")]
public string Tidkod { get; set; }
[XmlElement(ElementName = "datum", Namespace = "")]
public DateTime Datum { get; set; }
[XmlElement(ElementName = "timmar", Namespace = "")]
public double Timmar { get; set; }
[XmlAttribute(AttributeName = "anstid", Namespace = "")]
public int Anstid { get; set; }
[XmlText]
public string Text { get; set; }
[XmlElement(ElementName = "resenheter", Namespace = "")]
public Resenheter Resenheter { get; set; }
}
[XmlRoot(ElementName = "resenhet", Namespace = "")]
public class Resenhet
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public int Id { get; set; }
}
[XmlRoot(ElementName = "resenheter", Namespace = "")]
public class Resenheter
{
[XmlElement(ElementName = "resenhet", Namespace = "")]
public List<Resenhet> Resenhet { get; set; }
}
[XmlRoot(ElementName = "tidtransaktioner", Namespace = "")]
public class Tidtransaktioner
{
[XmlElement(ElementName = "tidtrans", Namespace = "")]
public List<Tidtrans> Tidtrans { get; set; }
}
[XmlRoot(ElementName = "dag", Namespace = "")]
public class Dag
{
[XmlAttribute(AttributeName = "datum", Namespace = "")]
public DateTime Datum { get; set; }
[XmlAttribute(AttributeName = "timmar", Namespace = "")]
public double Timmar { get; set; }
}
[XmlRoot(ElementName = "schema", Namespace = "")]
public class Schema
{
[XmlElement(ElementName = "dag", Namespace = "")]
public List<Dag> Dag { get; set; }
[XmlAttribute(AttributeName = "anstid", Namespace = "")]
public int Anstid { get; set; }
}
[XmlRoot(ElementName = "schematransaktioner", Namespace = "")]
public class Schematransaktioner
{
[XmlElement(ElementName = "schema", Namespace = "")]
public List<Schema> Schema { get; set; }
}
[XmlRoot(ElementName = "paxml", Namespace = "")]
public class Paxml
{
[XmlElement(ElementName = "header", Namespace = "")]
public Header Header { get; set; }
[XmlElement(ElementName = "dimensioner", Namespace = "")]
public Dimensioner Dimensioner { get; set; }
[XmlElement(ElementName = "resultatenheter", Namespace = "")]
public Resultatenheter Resultatenheter { get; set; }
[XmlElement(ElementName = "tidtransaktioner", Namespace = "")]
public Tidtransaktioner Tidtransaktioner { get; set; }
[XmlElement(ElementName = "schematransaktioner", Namespace = "")]
public Schematransaktioner Schematransaktioner { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = "http://www.paxml.se/2.0/paxml.xsd")]
public string NoNamespaceSchemaLocation { get; set; }
[XmlText]
public string Text { get; set; }
}
}
此 class 是由 XML 文件生成器生成的。如您所见,我一直在尝试添加 XML 属性以手动更改命名空间。
这是逻辑的 class:
using Logic.Mobigo.Services;
using Logic.Shared.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Logic.Services
{
public class XMLService
{
private readonly MobigoTimeService _mobigoTimeService;
private readonly MobigoUserService _mobigoUserService;
public XMLService(MobigoTimeService mobigoTimeService, MobigoUserService mobigoUserService)
{
_mobigoTimeService = mobigoTimeService;
_mobigoUserService = mobigoUserService;
}
public async Task<bool> Xml()
{
var timeRows = await _mobigoTimeService.List();
var xml = new Paxml();
xml.Header = new Header();
xml.Header.Format = "LÖNIN";
xml.Header.Version = 2.0;
var tidTrans = new List<Tidtrans>();
foreach (var timeRow in timeRows)
{
var user = await _mobigoUserService.GetByUserSign(timeRow.UserSign);
;
tidTrans.Add(new Tidtrans
{
Anstid = 1418, //int.Parse(user.EmployeeNr),
Tidkod = "SJK", //timeRow.TimeType.TimeCode,
//hur göra med datum vid månadsöverskridelse????
Datum = timeRow.StopDate,
Timmar = timeRow.TimeAmount,
});
}
xml.Tidtransaktioner = new Tidtransaktioner
{
Tidtrans = tidTrans,
};
var writer = new XmlSerializer(typeof(Paxml));
var path = "C:\Work\Git\LIM\PDF\" + "testfile.xml";
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, xml);
file.Close();
return true;
}
}
}
你离得不远,但你混淆了名称空间和值。您需要名称空间 http://www.w3.org/2001/XMLSchema-instance
中名为 noNamespaceSchemaLocation
且值为 http://www.paxml.se/2.0/paxml.xsd
的属性。看起来像这样:
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string NoNamespaceSchemaLocation { get; set; } = "http://www.paxml.se/2.0/paxml.xsd";
生成的根 XML 默认情况下如下所示:
<paxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="http://www.paxml.se/2.0/paxml.xsd" />
这在语义上与您的要求相同,因此不应导致任何问题。但是如果你真的想要摆脱xsd
的命名空间声明,你可以提供一个XmlSerializerNamespaces
只有你需要的命名空间:
var ns = new XmlSerializerNamespaces();
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
var serializer = new XmlSerializer(typeof(Paxml));
serializer.Serialize(file, xml, ns);