首页 文章

使用XSL对属性进行排序

提问于
浏览
10

我试图通过按名称(而不是值)对每个元素的属性进行排序来规范化某些XML数据的表示 . 这个想法是在添加或删除属性时保持文本差异最小,并防止不同的编辑者引入等效变体 . 这些XML文件受源代码控制,开发人员希望在不使用专门的XML工具的情况下对这些更改进行区分 .

我很惊讶没有找到如何做到这一点的XSL示例 . 基本上我只想要使用有序属性进行身份转换 . 我提出以下内容似乎适用于我的所有测试用例:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:template match="*|/|text()|comment()|processing-instruction()">
    <xsl:copy>
    <xsl:for-each select="@*">
        <xsl:sort select="name(.)"/>
        <xsl:copy/>
      </xsl:for-each>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

作为一个总的XSL n00b,我将不胜感激任何关于风格或效率的评论 . 我认为在这里发布它可能会有所帮助,因为它似乎至少不是一个常见的例子 .

2 回答

  • 2

    由于xslt是一种功能性语言,因此无法完全优化呼叫,因此执行for-each可能通常是我们人类最简单的路径,但对XSLT处理器来说效率最高 .

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
      <xsl:template match="*">
        <xsl:copy>
          <xsl:apply-templates select="@*">
            <xsl:sort select="name()"/>
          </xsl:apply-templates>
          <xsl:apply-templates/>
        </xsl:copy>
      </xsl:template>
      <xsl:template match="@*|comment()|processing-instruction()">
        <xsl:copy />     
      </xsl:template>
    </xsl:stylesheet>
    

    这在这方面是完全无足轻重的,作为“XSL n00b”,我认为你确实很好地解决了这个问题 .

  • 11

    为解决问题做得好 . 我假设您知道XML解析器的顺序或属性并不重要,因此本练习的主要好处是人类 - 机器将以不可预测的方式对输入或输出重新排序 .

    XML中的规范化并非易事,建议您使用任何合理的XML工具包提供的规范化程序,而不是编写自己的规范化程序 .

相关问题