我正在尝试基于文本 - XSLT 进行排序
I am trying to sorting based on Text - XSLT
我正在尝试基于文本进行排序,第一个文本应该是大写,然后其他文本以首字母大写或小写字母开头。
输入XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p content-type="emCase"><named-content content-type="emEntry">B</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">BTS, USA, Inc. v Executive Perspectives, LLC (Conn. Super, Oct. 16, 2014, No. X10CV116010685) 2014 Conn Super Lexis 2644, aff’d (Conn App 2016) 142 A3d 342:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">buySAFE, Inc. v Google, Inc. (Fed Cir 2014) 765 F3d 1350:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Babcock v Butler County (3d Cir 2015) 806 F3d 153:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Buxbom v Smith (1944) 23 C2d 535:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Byrd v Roadway Express, Inc. (5th Cir 1982) 687 F2d 85:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">B.K.B. v Maui Police Dep’t (9th Cir 2002) 276 F3d 1091:</named-content></p>
</root>
预期输出
<root>
<p content-type="emCase"><named-content content-type="emEntry">B</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">B.K.B. v Maui Police Dep’t (9th Cir 2002) 276 F3d 1091:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">BTS, USA, Inc. v Executive Perspectives, LLC (Conn. Super, Oct. 16, 2014, No. X10CV116010685) 2014 Conn Super Lexis 2644, aff’d (Conn App 2016) 142 A3d 342:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Babcock v Butler County (3d Cir 2015) 806 F3d 153:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Buxbom v Smith (1944) 23 C2d 535:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">buySAFE, Inc. v Google, Inc. (Fed Cir 2014) 765 F3d 1350:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Byrd v Roadway Express, Inc. (5th Cir 1982) 687 F2d 85:</named-content></p>
</root>
我的 XSLT 代码
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each select="p[named-content[@content-type='emEntry'][matches(., '^([A-Za-z]+)')]]">
<xsl:sort select="if(named-content[@content-type='emEntry' and matches(., '^([A-Z]+)')]) then named-content[@content-type='emEntry' and matches(., '^([A-Z]+)')] else upper-case(named-content[@content-type='emEntry'])" data-type="text" order="ascending"/>
<xsl:text>
</xsl:text>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
谁能帮我看看我的错误代码在哪里?
不确定我是否理解你的问题,这是你想要做的吗:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="p">
<xsl:sort select="named-content"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
要将大写字母排在小写字母之前,请使用 xsl:sort
的 case-order
属性。
这是一个简化的例子:
XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="p">
<xsl:sort select="named-content" data-type="text" order="ascending" case-order= "upper-first"/>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p>B.K.B. v Maui Police Dep’t (9th Cir 2002) 276 F3d 1091:</p>
<p>BTS, USA, Inc. v Executive Perspectives, LLC (Conn. Super, Oct. 16, 2014, No. X10CV116010685) 2014 Conn Super Lexis 2644, aff’d (Conn App 2016) 142 A3d 342:</p>
<p>Babcock v Butler County (3d Cir 2015) 806 F3d 153:</p>
<p>Buxbom v Smith (1944) 23 C2d 535:</p>
<p>Byrd v Roadway Express, Inc. (5th Cir 1982) 687 F2d 85:</p>
<p>buySAFE, Inc. v Google, Inc. (Fed Cir 2014) 765 F3d 1350:</p>
</root>
已添加:
我也不明白你想要实现什么逻辑来获得你显示的输出。
我可以通过按以下顺序对节点进行排序来获得相同的输出:
- 首字母开头的节点在前;
- 然后按字母顺序排序,忽略大小写。
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" 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="/root">
<xsl:copy>
<xsl:apply-templates select="p">
<xsl:sort select="number(matches(named-content, '^[A-Z](\.|[A-Z]|$)'))" data-type="number" order="descending"/>
<xsl:sort select="named-content" data-type="text" order="ascending" lang="en"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
演示:https://xsltfiddle.liberty-development.net/a9GPfN
</xsl:stylesheet>
以下符合您的要求吗? (要求很难理解。我假设有更简单和更快的 XSLT 代码来完成这个任务......)
它评估给定输入对预期输出的影响https://xsltfiddle.liberty-development.net/pNmC4J7
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="psStartingWithChar" match="p" use="upper-case(substring(translate(named-content/text(), translate(named-content/text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', ''), ''),1,1))"/>
<xsl:template match="root">
<xsl:variable name="ctxt">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:variable name="temp">
<xsl:for-each select="string-to-codepoints('ABCDEFGHIJKLMNOPQRSTUVWXYZ')">
<xsl:variable name="ch" select="codepoints-to-string(.)"/>
<xsl:variable name="root">
<xsl:for-each select="$ctxt">
<root>
<xsl:for-each select="key('psStartingWithChar',$ch)">
<xsl:copy-of select="."/>
</xsl:for-each>
</root>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="$root/root">
<xsl:copy>
<xsl:for-each select="p[named-content[@content-type='emEntry'][string-length(.)=1 or matches(translate(., translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', ''), ''), '^([^a-z]{2,})')]]">
<xsl:sort data-type="text" order="ascending"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
<xsl:for-each select="p[named-content[@content-type='emEntry'][not(string-length(.)=1 or matches(translate(., translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', ''), ''), '^([^a-z]{2,})'))]]">
<xsl:sort data-type="text" case-order= "upper-first" order="ascending"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<root>
<xsl:copy-of select="$temp/root/*"/>
</root>
</xsl:template>
</xsl:stylesheet>
我正在尝试基于文本进行排序,第一个文本应该是大写,然后其他文本以首字母大写或小写字母开头。
输入XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p content-type="emCase"><named-content content-type="emEntry">B</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">BTS, USA, Inc. v Executive Perspectives, LLC (Conn. Super, Oct. 16, 2014, No. X10CV116010685) 2014 Conn Super Lexis 2644, aff’d (Conn App 2016) 142 A3d 342:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">buySAFE, Inc. v Google, Inc. (Fed Cir 2014) 765 F3d 1350:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Babcock v Butler County (3d Cir 2015) 806 F3d 153:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Buxbom v Smith (1944) 23 C2d 535:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Byrd v Roadway Express, Inc. (5th Cir 1982) 687 F2d 85:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">B.K.B. v Maui Police Dep’t (9th Cir 2002) 276 F3d 1091:</named-content></p>
</root>
预期输出
<root>
<p content-type="emCase"><named-content content-type="emEntry">B</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">B.K.B. v Maui Police Dep’t (9th Cir 2002) 276 F3d 1091:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">BTS, USA, Inc. v Executive Perspectives, LLC (Conn. Super, Oct. 16, 2014, No. X10CV116010685) 2014 Conn Super Lexis 2644, aff’d (Conn App 2016) 142 A3d 342:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Babcock v Butler County (3d Cir 2015) 806 F3d 153:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Buxbom v Smith (1944) 23 C2d 535:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">buySAFE, Inc. v Google, Inc. (Fed Cir 2014) 765 F3d 1350:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Byrd v Roadway Express, Inc. (5th Cir 1982) 687 F2d 85:</named-content></p>
</root>
我的 XSLT 代码
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each select="p[named-content[@content-type='emEntry'][matches(., '^([A-Za-z]+)')]]">
<xsl:sort select="if(named-content[@content-type='emEntry' and matches(., '^([A-Z]+)')]) then named-content[@content-type='emEntry' and matches(., '^([A-Z]+)')] else upper-case(named-content[@content-type='emEntry'])" data-type="text" order="ascending"/>
<xsl:text>
</xsl:text>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
谁能帮我看看我的错误代码在哪里?
不确定我是否理解你的问题,这是你想要做的吗:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="p">
<xsl:sort select="named-content"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
要将大写字母排在小写字母之前,请使用 xsl:sort
的 case-order
属性。
这是一个简化的例子:
XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="p">
<xsl:sort select="named-content" data-type="text" order="ascending" case-order= "upper-first"/>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p>B.K.B. v Maui Police Dep’t (9th Cir 2002) 276 F3d 1091:</p>
<p>BTS, USA, Inc. v Executive Perspectives, LLC (Conn. Super, Oct. 16, 2014, No. X10CV116010685) 2014 Conn Super Lexis 2644, aff’d (Conn App 2016) 142 A3d 342:</p>
<p>Babcock v Butler County (3d Cir 2015) 806 F3d 153:</p>
<p>Buxbom v Smith (1944) 23 C2d 535:</p>
<p>Byrd v Roadway Express, Inc. (5th Cir 1982) 687 F2d 85:</p>
<p>buySAFE, Inc. v Google, Inc. (Fed Cir 2014) 765 F3d 1350:</p>
</root>
已添加:
我也不明白你想要实现什么逻辑来获得你显示的输出。
我可以通过按以下顺序对节点进行排序来获得相同的输出:
- 首字母开头的节点在前;
- 然后按字母顺序排序,忽略大小写。
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" 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="/root">
<xsl:copy>
<xsl:apply-templates select="p">
<xsl:sort select="number(matches(named-content, '^[A-Z](\.|[A-Z]|$)'))" data-type="number" order="descending"/>
<xsl:sort select="named-content" data-type="text" order="ascending" lang="en"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
演示:https://xsltfiddle.liberty-development.net/a9GPfN
</xsl:stylesheet>
以下符合您的要求吗? (要求很难理解。我假设有更简单和更快的 XSLT 代码来完成这个任务......)
它评估给定输入对预期输出的影响https://xsltfiddle.liberty-development.net/pNmC4J7
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="psStartingWithChar" match="p" use="upper-case(substring(translate(named-content/text(), translate(named-content/text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', ''), ''),1,1))"/>
<xsl:template match="root">
<xsl:variable name="ctxt">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:variable name="temp">
<xsl:for-each select="string-to-codepoints('ABCDEFGHIJKLMNOPQRSTUVWXYZ')">
<xsl:variable name="ch" select="codepoints-to-string(.)"/>
<xsl:variable name="root">
<xsl:for-each select="$ctxt">
<root>
<xsl:for-each select="key('psStartingWithChar',$ch)">
<xsl:copy-of select="."/>
</xsl:for-each>
</root>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="$root/root">
<xsl:copy>
<xsl:for-each select="p[named-content[@content-type='emEntry'][string-length(.)=1 or matches(translate(., translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', ''), ''), '^([^a-z]{2,})')]]">
<xsl:sort data-type="text" order="ascending"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
<xsl:for-each select="p[named-content[@content-type='emEntry'][not(string-length(.)=1 or matches(translate(., translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', ''), ''), '^([^a-z]{2,})'))]]">
<xsl:sort data-type="text" case-order= "upper-first" order="ascending"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<root>
<xsl:copy-of select="$temp/root/*"/>
</root>
</xsl:template>
</xsl:stylesheet>