这是我输入的xml。xml 最多可以有 3 个节点和最少 1 个节点。输入 xml 可以具有的最小节点,如下所示
<Root>
<node>uniquename</node>
</Root>
输入 xml 可以具有的最大节点数如下。包含节点的唯一名称将始终存在。
以下示例所需输出的示例输入 XML
<Root>
<node>abc</node>
<node>e1</node>
<node>uniquename2</node>
</Root>
值"abc"对于所有输入 xml 都是通用的。 值 E1 类似于版本号。它可以有 e1 到 e9。它也可以有一个次要版本,如 e1.1 到 e9.9。第三个节点是唯一的。我的输出应该是下面的文本,下面的示例作为所需的输出
Unique name with version from the xml - uniquename2e1
version number - e1
common name - Present in the input
输入 xml 节点的顺序各不相同,即有时版本号可以位于顶部,有时唯一名称可以位于顶部。通用名称也是如此。尽管如此,我的输出应该具有唯一名称,后跟版本号。 如果输入 xml 中没有通用名称,则输出文本应指示,它不存在
如果输入中没有版本号,则输出中的版本号行可以为空
Unique name with version from the xml - uniquename3
common name - Present/Absent in the input.
虽然我没有 xslt 2.0 处理器,但我的 xslt 处理器支持 xmlns:regexp="http://exslt.org/regular-expressions",我想用它来查找版本控制部分。
编辑
唯一名称是不遵循版本号模式的内容,^ed(.d)*$
或不是通用名称
此 XSLT 1.0 转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output method="text"/>
<my:commonAbsent/>
<xsl:variable name="vVer" select=
"/*/node
[starts-with(., 'e')
and
number(substring(.,2)) = number(substring(.,2))]"/>
<xsl:template match="/*">
<xsl:apply-templates mode="unique" select=
"node[not(. = 'abc'
or
generate-id() =generate-id($vVer)
)
]"/>
<xsl:apply-templates select="$vVer" mode="ver"/>
<xsl:apply-templates select=
"node[. = 'abc']
|
document('')
[not(current()/node[.='abc'])]
/*/my:commonAbsent
"/>
</xsl:template>
<xsl:template match="node" mode="unique">
Unique name with version from the xml - <xsl:text/>
<xsl:value-of select="concat(., $vVer)"/>
</xsl:template>
<xsl:template match="node" mode="ver">
Version number - <xsl:value-of select="$vVer"/>
</xsl:template>
<xsl:template match="node[. = 'abc']">
Common name - Present in the input
</xsl:template>
<xsl:template match="my:commonAbsent">
Common name - Absent in the input
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<Root>
<node>abc</node>
<node>e1</node>
<node>uniquename2</node>
</Root>
产生所需的正确结果:
Unique name with version from the xml - uniquename2e1
Version number - e1
Common name - Present in the input
当对没有"公用名"的 XML 文档应用相同的转换时:
<Root>
<node>e1</node>
<node>uniquename2</node>
</Root>
再次产生正确的、想要的结果:
Unique name with version from the xml - uniquename2e1
Version number - e1
Common name - Absent in the input
最后,如果 XML 文档中未表示"版本":
<Root>
<node>abc</node>
<node>uniquename2</node>
</Root>
再次应用相同的转换会产生所需的正确结果:
Unique name with version from the xml - uniquename2
Common name - Present in the input
解释:
结果树中节点的顺序(在这些情况下,它们都是文本节点)完全由选择执行生成这些结果树节点的模板的xsl:apply-templates
指令的顺序决定。
我没有测试过这个,因为我无法访问 EXSLT,但这个样式表应该可以工作..此外,此脚本中还有很大的改进空间,例如将节点放入变量中,这样就不必重复计算它们,以及在 not( 条件下使用 xsl:select 而不是 xsl:if 和 xsl:if)。因此,请考虑这是快速而肮脏的版本。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:regexp="http://exslt.org/regular-expressions"
extension-element-prefixes="regexp">
<xsl:import href="regexp.xsl" />
<xsl:output method="text" />
<xsl:template match="/">
<xsl:value-of select="Root/node[.!='abc'][regexp:test(.,'^ed(.d)*$','')]" /><xsl:value-of select="Root/node[regexp:test(.,'^ed(.d)*$','')]" />
<xsl:if test="Root/node[regexp:test(.,'^ed(.d)*$','')]">
version number - <xsl:value-of select="Root/node[regexp:test(.,'^ed(.d)*$','')]" />
</xsl:if>
<xsl:if test="Root/node[.='abc']">
common name - Present in the input
</xsl:if>
<xsl:if test="not( Root/node[.='abc'])">
common name - Absent in the input
</xsl:if>
</xsl:template>
</xsl:stylesheet>