非字母非数字顺序的 XSLT Order 类 | the
本文介绍了非字母非数字顺序的 XSLT Order 类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述 我已经研究过这个问题,但我发现的建议似乎相当复杂,而且适用于更一般的情况.对于这个场景,或许有更简洁的解决方案,也就是更具体.
我有大量的 html 文件,如下所示:
<头><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><title>t</title>头部><身体><div class="a"><div class="f">f1</div><div class="e">e1</div><div class="e">e2</div><div class="g">g</div><div class="c">c1</div><div class="b"><div class="ba">ba</div><div class="bb">bb</div>
<div class="c">c2</div><div class="f">f2</div><div class="d">d</div><div class="c">c3</div>
...
</html>
规则 1 我想以非字母和非数字的类属性的特定顺序对 div class="a" 内的 div 进行排序.出于本示例的目的,我们的最终顺序如下:
在我的真实例子中,列表要长得多.
规则 2 如果对于给定的类属性有多个节点,那么它们应该以与原始文件中相同的顺序保留,例如:
请注意,在我的真实示例中,这些值不会按字母数字顺序排列.
规则 3 不能影响子节点的顺序,例如:
请注意,在我的真实示例中,这些值也不会按字母数字顺序排列.
最终输出应如下所示:
<头><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><title>t</title>头部><身体><div class="a"><div class="g">g</div><div class="f">f1</div><div class="f">f2</div><div class="b"><div class="ba">ba</div><div class="bb">bb</div><div class="c">c1</div><div class="c">c2</div><div class="c">c3</div><div class="e">e1</div><div class="e">e2</div><div class="d">d</div>
...</html>
我一开始想:
在类属性值前添加一个数字,例如将 class="g" 重命名为 class="01g" 等 按字母数字顺序排列类 删除数字,例如将 class="01g" 重命名为 class="g" 等 但是我不喜欢这个解决方案,因为它需要太多的转换.
我真正想要的是提出更优雅的解决方案.也许我会定义一个有序的类值列表,一个聪明的索引会以某种方式将节点按定义的顺序排列?
您有什么建议可以添加到我的 xslt 模板中吗?
<xsl:output omit-xml-declaration="yes" indent="yes"/><xsl:strip-space elements="*"/><xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:模板></xsl:stylesheet>
解决方案
AFAICT,你想做如下事情:
XSLT 1.0
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/><xsl:strip-space elements="*"/><!-- 身份变换--><xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:模板><xsl:template match="div[@class='a']"><xsl:variable name="sort-order">gfbced</xsl:variable><xsl:copy><xsl:apply-templates select="@*|node()"><xsl:sort select="string-length(substring-before($sort-order, @class))" data-type="number" order="ascending"/></xsl:apply-templates></xsl:copy></xsl:模板></xsl:stylesheet>
要容纳不是单个字符的类值,您可以使用:
<xsl:variable name="sort-order">|g|f|b|c|e|d|</xsl:variable><xsl:copy><xsl:apply-templates select="@*|node()"><xsl:sort select="string-length(substring-before($sort-order, concat('|', @class, '|')))" data-type="number" order="ascending"/></xsl:apply-templates></xsl:copy></xsl:模板>
I have researched this problem but the suggestions that I have found seems to be rather convoluted and for a more general scenario. Perhaps there is a more concise solution for this scenario, that is more specific.
I have a large number of html files like the following:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>t</title>
</head>
<body>
<div class="a">
<div class="f">f1</div>
<div class="e">e1</div>
<div class="e">e2</div>
<div class="g">g</div>
<div class="c">c1</div>
<div class="b">
<div class="ba">ba</div>
<div class="bb">bb</div>
</div>
<div class="c">c2</div>
<div class="f">f2</div>
<div class="d">d</div>
<div class="c">c3</div>
</div>
...
</body>
</html>
Rule # 1 I want to order the div's inside div class="a" in a specific order of their class attribute that is non-alphabetic and non-numeric. For the purpose of this example, let's the final order be the following:
In my real examples, the list is much longer.
Rule # 2 If for a given class attribute there is more than one node, then they should be left in the same order as in the original file, for instance:
Please notice that in my real examples these values would not be in alphanumerical order.
Rule # 3 The order of child nodes must not be affected, for instance:
Please notice that in my real examples these values would not be in alphanumerical order either.
The final output should be like the following:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>t</title>
</head>
<body>
<div class="a">
<div class="g">g</div>
<div class="f">f1</div>
<div class="f">f2</div>
<div class="b">
<div class="ba">ba</div>
<div class="bb">bb</div>
</div>
<div class="c">c1</div>
<div class="c">c2</div>
<div class="c">c3</div>
<div class="e">e1</div>
<div class="e">e2</div>
<div class="d">d</div>
</div>
...
</body>
</html>
I have thought at first to:
Prepend a number to the class attribute value, for instance rename class="g" to class="01g", etc Order the classes in alphanumerical order Remove the number, for instance rename class="01g" to class = "g", etc However I dislike this solution because it requires too many transformations.
What I would really like is to come up with a more elegant solutions. Perhaps I would define an ordered list of class values and a clever index would somehow put the nodes in that defined order?
Do you have any suggestions to add to my xslt template?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
解决方案
AFAICT, you want to do something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[@class='a']">
<xsl:variable name="sort-order">gfbced</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="string-length(substring-before($sort-order, @class))" data-type="number" order="ascending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
To accommodate class values that are not single characters, you can use:
<xsl:template match="div[@class='a']">
<xsl:variable name="sort-order">|g|f|b|c|e|d|</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="string-length(substring-before($sort-order, concat('|', @class, '|')))" data-type="number" order="ascending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
这篇关于非字母非数字顺序的 XSLT Order 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-27 04:01