Xml XSLT根据优先级在相同节点之间进行选择

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:

<?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>&#xa;</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>&#xa;</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>&#10;</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, '&#10;')"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>