[英]Transform style XML in C# with XmlDocument
我正在尝试对 XML 文件进行一些添加。 我正在以一种格式(下面的格式 2)添加 XML,并希望将其转换为另一种格式(下面的格式 1)。 我怎样才能做到这一点?
细节:
我有一个用于创建文件的template.xml
,因此我可以将它导入到一个特殊的应用程序中,该应用程序仅通过更新现有属性来获取xml
。 但是,根据某些情况,需要添加更多元素和属性。
XML 的一个简化示例如下:
<?xml version="1.0"?>
<chssystem ExportDate="2/21/2018" ExportTime="2:57 PM EST" DateFormat="MM/dd/yyyy" NumberFormat="HH:mm:ss " SchemaValidation="true" ExportVersion="2016.1.SP1710.57" xmlns="http://www.mentor.com/harness/Schema/LibrarySchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mentor.com/harness/Schema/LibrarySchema file:/C:/MentorGraphics/VeSys_Client/dtd/LibrarySchema.xsd" XMLVersion="1.6">
<librarycomponenttype librarycomponenttype_id="_GROUPID_CONNECTOR" description="Connector" clipgromident="" typecode="CONN" />
<connectorpart libraryobject_id="_OID_CTEST" depth="0.0" description="TEST DATA" graphics="0" groupname="Connector" librarycomponenttype_id="_GROUPID_CONNECTOR" cavityqt="1" partnumber="CONN-C-TEST" unitofmeasure="Each" >
<librarycavity librarycavity_id="ID1" ca_mappingtype="Userdefined" ca_attach=" " isblocked="1" pingraphic=" " cavityname="1" librarypincontainer_id="_OID_CTEST" sortorder="1"/>
</connectorpart>
</chssystem>
假设我想添加这个Format1
<subsystem name="hahaha"
tag1="NoNo"tag2="SoNo" />
这是我用来创建此元素的 c# 代码:
XmlElement subsystem = xmlDoc.CreateElement("subsystem");
XmlElement name= xmlDoc.CreateElement("name");
name.InnerText = "hahaha";
XmlElement tag1= xmlDoc.CreateElement("tag1");
tag1.InnerText = "NoNo";
XmlElement tag2= xmlDoc.CreateElement("tag2");
tag2.InnerText = "SoNo";
在我附加它们之后,我有一个具有以下格式的新 XML
<subsystem xmlns="">
<name>hahaha</name>
<tag1>NoNo</tag1>
<tag2>SoNo</tag2>
</subsystem >
所以 C# 代码添加了额外的xmlns=""
无论是否有额外的xmlns=""
应用程序仍然返回错误
如果我手动将数据调整为Format1,就没有错误~~~~> 如果我可以将Format2转换为Format1 ,我认为应用程序会接受xml
来自应用程序的错误:如果我保留xmlns=""
,错误消息是Invalid content was found starting with element subsystem, the element name is needed
如果我删除xmlns=""
,错误消息是element name must appear on subsystem, element tag1 must appear on subsystem, element tag2 must appear on subsystem
这里有两个基本问题。
首先,您将name
、 tag1
和tag2
创建为子XML 元素,而您应该将它们创建为XML 属性。 即下面的两个 XML 片段是不等价的,因为第一个中的<name>hahaha</name>
是一个元素,而name="hahaha"
不是:
<subsystem>
<name>hahaha</name>
</subsystem>
<subsystem name="hahaha" />
在您当前的代码中,您正在创建元素,但您应该创建XmlAttribute
对象,例如使用XmlDocument.CreateAttribute()
。
(有关元素和属性之间差异的概述,请参见例如XSD:元素和属性之间的差异或XML 属性与 XML 元素之间的差异。)
其次,您正在使用XmlDocument.CreateElement(string qualifiedName)
在空命名空间中创建<subsystem>
节点。 但是,根元素<chssystem>
属于"http://www.mentor.com/harness/Schema/LibrarySchema"
命名空间,这要归功于xmlns="http://www.mentor.com/harness/Schema/LibrarySchema"
属性。 因此,您需要在相同的命名空间中创建您的<subsystem>
节点,例如使用XmlDocument.CreateElement(String qualifiedName, String namespaceURI)
。
(有关 XML 名称空间的概述,请参见例如什么是 XML 名称空间? 。)
解决这两个问题的方法是修改您的代码以正确创建<subsystem>
,而不是错误地创建它并尝试对其进行转换。 以下代码应该可以完成这项工作:
// Get the XML namespace of the root element.
var namespaceURI = xmlDoc.DocumentElement.NamespaceURI;
// Create the subsystem in the same XML namespace
var subsystem = xmlDoc.DocumentElement.AppendChild(xmlDoc.CreateElement("subsystem", namespaceURI));
// Add the specified attributes.
subsystem.Attributes.Append(xmlDoc.CreateAttributeWithValue("name", "hahaha"));
subsystem.Attributes.Append(xmlDoc.CreateAttributeWithValue("tag1", "NoNo"));
subsystem.Attributes.Append(xmlDoc.CreateAttributeWithValue("tag2", "SoNo"));
它使用扩展方法:
public static class XmlNodeExtensions
{
public static XmlAttribute CreateAttributeWithValue(this XmlDocument doc, string name, string value)
{
var attr = doc.CreateAttribute(name);
attr.Value = value;
return attr;
}
}
并生成以下 XML:
<chssystem ExportDate="2/21/2018" ExportTime="2:57 PM EST" DateFormat="MM/dd/yyyy" NumberFormat="HH:mm:ss " SchemaValidation="true" ExportVersion="2016.1.SP1710.57" xmlns="http://www.mentor.com/harness/Schema/LibrarySchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mentor.com/harness/Schema/LibrarySchema file:/C:/MentorGraphics/VeSys_Client/dtd/LibrarySchema.xsd" XMLVersion="1.6">
<librarycomponenttype librarycomponenttype_id="_GROUPID_CONNECTOR" description="Connector" clipgromident="" typecode="CONN" />
<connectorpart libraryobject_id="_OID_CTEST" depth="0.0" description="TEST DATA" graphics="0" groupname="Connector" librarycomponenttype_id="_GROUPID_CONNECTOR" cavityqt="1" partnumber="CONN-C-TEST" unitofmeasure="Each">
<librarycavity librarycavity_id="ID1" ca_mappingtype="Userdefined" ca_attach=" " isblocked="1" pingraphic=" " cavityname="1" librarypincontainer_id="_OID_CTEST" sortorder="1" />
</connectorpart>
<subsystem name="hahaha" tag1="NoNo" tag2="SoNo" />
</chssystem>
示例工作.Net 小提琴。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.