Xml XSLT根据优先级在相同节点之间进行选择
我一直在努力根据优先级从一系列相同的节点中选择正确的节点 这是XML:Xml XSLT根据优先级在相同节点之间进行选择,xml,xslt,xpath,Xml,Xslt,Xpath,我一直在努力根据优先级从一系列相同的节点中选择正确的节点 这是XML: <?xml version="1.0" encoding="UTF-8"?> <LandXML> <CgPoints> <CgPoint name="name1" oID="id1"></CgPoint> <CgPoint name="name2" oID="id2"></CgPoint> &l
<?xml version="1.0" encoding="UTF-8"?>
<LandXML>
<CgPoints>
<CgPoint name="name1" oID="id1"></CgPoint>
<CgPoint name="name2" oID="id2"></CgPoint>
<CgPoint name="name3" oID="id1"></CgPoint>
<CgPoint name="name4" oID="id1"></CgPoint>
<CgPoint name="name5" oID="id2"></CgPoint>
<CgPoint name="name6" oID="id3"></CgPoint>
</CgPoints>
<Points>
<Point uniqueID="name1" class="medium" text="text1"></Point>
<Point uniqueID="name2" class="medium" text="text2"></Point>
<Point uniqueID="name3" class="high" text="text3"></Point>
<Point uniqueID="name4" class="low" text="text4"></Point>
<Point uniqueID="name5" class="low" text="text5"></Point>
<Point uniqueID="name6" class="medium" text="text6"></Point>
</Points>
</LandXML>
这是我到目前为止提出的xslt:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
<xsl:output method="text" indent="no" encoding="utf-8"/>
<xsl:variable name="fileExt" select="'txt'"/>
<!-- Comma separator -->
<xsl:variable name="separator" select="','"/>
<xsl:key name="keyHPoint" match="/LandXML/Points/Point" use="@uniqueID"/>
<xsl:template match="/">
<xsl:apply-templates select="/LandXML/CgPoints/CgPoint">
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/LandXML/CgPoints/CgPoint">
<xsl:variable name="name" select="./@name"/>
<xsl:variable name="id" select="./@oID"/>
<xsl:variable name="allpoints" select="/LandXML/CgPoints/CgPoint[@oID = $id]"/>
<xsl:variable name="Point1" select="key('keyHPoint', $allpoints/@oID)"/>
<xsl:choose>
<xsl:when test="count($allpoints) = 1">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/Point[@uniqueID = $name]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$Point1[@class = 'high']">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/Point[@uniqueID = $name]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$Point1[@class = 'medium']">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/Point[@uniqueID = $numurs]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$Point1[@class = 'low']">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/h:Point[@uniqueID = $name]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Text template -->
<xsl:template match="/LandXML/Points/Point">
<xsl:value-of select="concat(./@text, $separator)"/>
</xsl:template>
<!-- New line -->
<xsl:template name="newline">
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
;
有了这个xslt,我得到了所有节点的输出,没有应用按优先级选择。
提前感谢您的帮助 使用XSLT 2或3,您可以按
oID
属性分组,按引用的类对每个组进行排序(例如,按可能的值序列获取的索引),然后按排序顺序()输出第一个组:
对于XSLT 1,您可以以某种方式使用相同的算法,只需使用键进行分组和Muenchian分组以及排序,例如,通过获取其余类值串联的字符串长度():
是否仅限于XSLT 1?是的,很遗憾,只能使用XSLT 1.0
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
<xsl:output method="text" indent="no" encoding="utf-8"/>
<xsl:variable name="fileExt" select="'txt'"/>
<!-- Comma separator -->
<xsl:variable name="separator" select="','"/>
<xsl:key name="keyHPoint" match="/LandXML/Points/Point" use="@uniqueID"/>
<xsl:template match="/">
<xsl:apply-templates select="/LandXML/CgPoints/CgPoint">
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/LandXML/CgPoints/CgPoint">
<xsl:variable name="name" select="./@name"/>
<xsl:variable name="id" select="./@oID"/>
<xsl:variable name="allpoints" select="/LandXML/CgPoints/CgPoint[@oID = $id]"/>
<xsl:variable name="Point1" select="key('keyHPoint', $allpoints/@oID)"/>
<xsl:choose>
<xsl:when test="count($allpoints) = 1">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/Point[@uniqueID = $name]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$Point1[@class = 'high']">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/Point[@uniqueID = $name]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$Point1[@class = 'medium']">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/Point[@uniqueID = $numurs]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$Point1[@class = 'low']">
<xsl:value-of select="concat($id, $separator)"/>
<xsl:apply-templates select="/LandXML/Points/h:Point[@uniqueID = $name]"/>
<xsl:call-template name="newline">
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Text template -->
<xsl:template match="/LandXML/Points/Point">
<xsl:value-of select="concat(./@text, $separator)"/>
</xsl:template>
<!-- New line -->
<xsl:template name="newline">
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="class-order" as="xs:string*" select="'high', 'medium', 'low'"/>
<xsl:output method="text"/>
<xsl:key name="pref" match="Point" use="@uniqueID"/>
<xsl:template match="/">
<xsl:for-each-group select="LandXML/CgPoints/CgPoint" group-by="@oID">
<xsl:for-each select="current-group()">
<xsl:sort select="index-of($class-order, key('pref', @name)/@class)"/>
<xsl:if test="position() eq 1">
<xsl:value-of select="current-grouping-key(), key('pref', @name)/@text" separator=","/>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:param name="class-order" select="'high|medium|low'"/>
<xsl:output method="text"/>
<xsl:key name="point-group" match="CgPoint" use="@oID"/>
<xsl:key name="pref" match="Point" use="@uniqueID"/>
<xsl:template match="/">
<xsl:for-each select="LandXML/CgPoints/CgPoint[generate-id() = generate-id(key('point-group', @oID)[1])]">
<xsl:for-each select="key('point-group', @oID)">
<xsl:sort select="string-length(substring-after($class-order, key('pref', @name)/@class))" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="concat(@oID, ',', key('pref', @name)/@text, ' ')"/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>