草庐IT

xml - 用于订购属性的 XSLT

coder 2024-06-28 原文

如何使用 XSLT 控制属性排序?

我有一个输入 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>

我需要应用 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>

唯一的变化是 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>

mytest.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <attributes>
        <attribute>b:type</attribute>
        <attribute>id</attribute>
    </attributes>

最佳答案

Attribute order is insignificant根据 XML Recommendation :

Note that the order of attribute specifications in a start-tag or empty-element tag is not significant.

因此,XSLT 无法控制输出的属性排序。

W3C 推荐中的属性排序

一般来说,XML 推荐都认为属性顺序是无关紧要的,但请参阅 section on attribute processingXML Normalization RecommendationCanonical XML Recommendation如果您的应用程序需要属性排序。但是,您必须在标准 XSLT 之外执行此操作。

属性排序实现技巧

如果您认识到对 XML 属性强加顺序存在本质上的缺陷,有悖于互操作性,并且完全不符合 XML 推荐标准和使用 XML 的既定实践,但您仍然 必须控制属性排序,这里有一些实现这种控制的方法...

正如 Michael Kay 在这个问题的另一个答案中提到的,Saxon 9.5(PE 或更高版本)有一个 XSLT 扩展,可以控制序列化程序的属性排序。参见 saxon:attribute-order了解详情。

您可以对标准 XSLT 生成的 XML 进行后处理。在 XML 库级别下操作,您当然可以通过字符或字符串级别处理获得对属性排序的完全词法控制。

您可以依赖 XML 库提供的排序的实现细节。例如,某些库会根据属性名称按字母顺序写出属性,或者保留提供给它们的属性顺序。显然,依赖实现细节本质上是不可靠的。也就是说,例如 XMLStreamWriter.writeAttribute 的实现很可能将来会继续遵守赋予它们的属性顺序。

最后一次重申所有 XML 属性排序问题的真正答案是在关闭之前按顺序...

将 XML 属性视为具有顺序与 XML Recommendation 相反并且应该避免。

关于xml - 用于订购属性的 XSLT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19718597/

有关xml - 用于订购属性的 XSLT的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  6. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  7. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  8. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  9. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  10. ruby - Chef Ruby 遍历 .erb 模板文件中的属性 - 2

    所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP

随机推荐