通过标准DOM处理XML时,序列化后不保证属性顺序.最后,这就是我在使用标准java XML Transform API序列化输出时所实现的.
但是我确实需要保留订单.我想知道Java是否有任何可能性来保持通过DOM API处理的XML文件的原始属性顺序,或任何强制命令的方式(可能通过使用替代序列化API来设置此一种财产).在我的情况下,处理减少以改变具有一堆属性的相同元素的序列的一些属性(不是全部)的值,并且可以插入更多元素.
有没有"简单"的方法,还是我必须定义自己的XSLT转换样式表来指定输出并更改整个输入XML文件?
更新我必须感谢你的所有答案.答案似乎比我预期的更明显.我从未关注属性顺序,因为我之前从未需要它.
需要属性顺序的主要原因是生成的XML文件看起来不同.目标是一个包含数百个警报的配置文件(每个警报由一组属性定义).这个文件通常随着时间的推移几乎没有什么修改,但是保持它的顺序是很方便的,因为当我们需要修改它的东西时,它是手工编辑的.有时,一些项目需要对此文件进行轻微修改,例如将其中一个属性设置为客户特定代码.
我刚开发了一个小应用程序来合并原始文件(所有项目通用)和每个项目的特定部分(修改某些属性的值),因此特定于项目的文件获取基础文件的更新(新警报定义或某些属性)价值错误修正).我需要有序属性的主要动机是能够通过文本比较工具(例如Winmerge)检查应用程序的输出.如果格式(主要是属性顺序)保持不变,则可以很容易地发现差异.
我真的认为这是可能的,因为XML处理程序(如XML Spy)允许您编辑XML文件并应用一些排序(网格模式).也许我唯一的选择是使用其中一个程序来手动修改输出文件.
我试图使用XmlSerializer和继承序列化一些对象,但我在排序结果时遇到了一些问题.
下面是一个类似于我设置的示例:〜
public class SerializableBase
{
[XmlElement(Order = 1)]
public bool Property1 { get; set;}
[XmlElement(Order = 3)]
public bool Property3 { get; set;}
}
[XmlRoot("Object")]
public class SerializableObject1 : SerializableBase
{
}
[XmlRoot("Object")]
public class SerializableObject2 : SerializableBase
{
[XmlElement(Order = 2)]
public bool Property2 { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我想要的结果如下:〜
<Object>
<Property1></Property1>
<Property2></Property2>
<Property3></Property3>
</Object>
Run Code Online (Sandbox Code Playgroud)
但是我得到的结果是:〜
<Object>
<Property1></Property1>
<Property3></Property3>
<Property2></Property2>
</Object>
Run Code Online (Sandbox Code Playgroud)
有谁知道它是否可能或任何替代方案?
谢谢
我有以下接受文件名的变量:
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
Run Code Online (Sandbox Code Playgroud)
我想改变它,以便我可以传入一个对象.我不想首先将对象序列化为文件.
这可能吗?
更新:
我最初的意图是获取一个xml文档,合并一些xslt(存储在一个文件中),然后输出并返回html ...像这样:
public string TransformXml(string xmlFileName, string xslFileName)
{
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(xd, null, stm);
stm.Position = 1;
var sr = new StreamReader(stm);
xtr.Close();
return sr.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我正在从文件中读取xml.现在我想要做的就是在将对象序列化到文件之前使用它.
那么让我用代码来说明我的问题
public string TransformXMLFromObject(myObjType myobj , string xsltFileName) …Run Code Online (Sandbox Code Playgroud) XmlElement具有"Order"属性,您可以使用该属性在使用XmlSerializer进行序列化时指定属性的精确顺序(无论如何相互关联).
XmlAttribute是否有类似的东西?我只是想从类似的东西设置属性的顺序
public class bookingList
{
[XmlElement(Order = 1)]
public string error { get; set; }
[XmlElement(Order = 2)]
public int counter { get; set; }
[XmlElement(ElementName = "booking", Order = 3)]
public List<booking> bookings = new List<booking>();
}
Run Code Online (Sandbox Code Playgroud)
至
<MyType end="bob" start="joe" />
Run Code Online (Sandbox Code Playgroud)
这只是为了可读性,真的是我自己的利益.
我正在编写一个java程序,它读取xml文件,进行一些修改,然后写回xml.
使用标准java xml DOM api,不保留属性的顺序.也就是说,如果我有一个输入文件,例如:
<person first_name="john" last_name="lederrey"/>
Run Code Online (Sandbox Code Playgroud)
我可能会得到一个输出文件:
<person last_name="lederrey" first_name="john"/>
Run Code Online (Sandbox Code Playgroud)
这是正确的,因为XML规范说订单属性并不重要.
但是,我的程序需要保留属性的顺序,以便人们可以轻松地将输入和输出文档与diff工具进行比较.
一个解决方案是使用SAX(而不是DOM)处理文档: DOM处理后的XML属性顺序
但是,这对我的情况不起作用,因为我需要在一个节点中进行的转换可能取决于整个文档中的XPATH表达式.所以,最简单的方法是让一个xml库与标准java DOM lib非常相似,但它保留了属性顺序.
有没有这样的图书馆?
ps:请避免讨论是否应该保留属性顺序.这是一个非常有趣的讨论,但这不是这个问题的重点.
有没有办法让System.Xml.Serialization以特定顺序序列化属性?我正在创建新的xml导出,并且当前属性的顺序不同。我知道属性顺序无关紧要,但是我必须将此xml发送到可能没有这种开明思路的服务器。
我正在编写一个生成几个XML文件的应用程序.在文件中,一些标签具有属性.我想知道属性的顺序是否重要,或者它是否相同.
例如,这个输出:
<person first='john' last='doe'>
Run Code Online (Sandbox Code Playgroud)
与此相同:
<person last="doe" first="john">
Run Code Online (Sandbox Code Playgroud) 我有一个输入XML文档:
输入XML
<?xml version="1.0" encoding="UTF-8"?>
<allNames id="ID_0" b:type="a:UnstructuredName">
<typeName>KnownBy</typeName>
<startDate>2001-01-01-05:00</startDate>
<fullName>ABCD 004 COMPANY INC</fullName>
</allNames>
Run Code Online (Sandbox Code Playgroud)
我需要应用XSLT将其转换为
输出XML
<?xml version="1.0" encoding="UTF-8"?>
<allNames b:type="a:UnstructuredName" id="ID_0">
<typeName>KnownBy</typeName>
<startDate>2001-01-01-05:00</startDate>
<fullName>ABCD 004 COMPANY INC</fullName>
</allNames>
Run Code Online (Sandbox Code Playgroud)
唯一的变化是元素中的属性排序更改allNames.我查了另一篇文章并编写了命令属性的XSLT,但我不知道如何让整个工作正常.
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="attributes" select="document('mytest.xml')//attribute"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="self" select="."/>
<xsl:for-each select="$attributes">
<xsl:apply-templates select="$self/@*[name()=current()]"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
mytest.xml
<?xml version="1.0" encoding="UTF-8"?>
<attributes> …Run Code Online (Sandbox Code Playgroud)