XSLT排序顺序以匹配不同父节点的顺序

时间:2015-06-10 16:52:52

标签: xml xslt

我有两个偶然共享其数据子集的节点。我需要根据第二组的原始顺序对第一组进行排序。

举一个例子,考虑以下几组点和线。每一个"开始"和"结束"在每种情况下,每一行的点也会列在“点数”列表中。

<Points>
    <Point name="Point1">0 0</Point>
    <Point name="Point2">0 1</Point>
    <Point name="Point3">1 1</Point>
    <Point name="Point4">1 0</Point>
</Points>

<Shape>
    <Line name="Line1">
        <Start>0 0</Start>
        <End>0 1</End>
    </Line>
    <Line name="Line2">
        <Start>0 1</Start>
        <End>1 1</End>
    </Line>
    <Line name="Line3">
        <Start>1 1</Start>
        <End>1 0</End>
    </Line>
    <Line name="Line4">
        <Start>1 0</Start>
        <End>0 0</End>
    </Line>
</Shape>

我需要对Points进行排序,以使值与为Shape列出的End points的顺序相同。

对于上面的例子,预期的XSLT输出如下......

Point2 0 1
Point3 1 1
Point4 1 0
Point1 0 0

具体来说,我正在使用AutoCAD中的COGO Points和Alignment对象,尝试根据Civil3D的LandXML输出自定义报告。上面的示例只是为了给我一些方向。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

  

总是会有与终点相同的点数。

在这种情况下,问题可以重申为:

  

按文档顺序列出所有终点,以及   对应的点名称。

实现这一目标的最佳方法是使用 key - 例如(简化说明原理):

XSLT 1.0

<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:key name="pt" match="Point" use="." />

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each select="Shape/Line">
            <xsl:copy-of select="key('pt', End)"/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

<强>结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <Point name="Point2">0 1</Point>
  <Point name="Point3">1 1</Point>
  <Point name="Point4">1 0</Point>
  <Point name="Point1">0 0</Point>
</root>

答案 1 :(得分:0)

我认为这应该有效:一个匹配End个节点的模板,并使用相同的文本值抓取Point节点(第二个模板匹配所有text()以确保它不会没有意外输出:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="/root/Shape/Line/End">
        <xsl:variable name="endPtText" select="./text()" />
        <xsl:value-of select="/root/Points/Point[text() = $endPtText]/@name" /><xsl:text> </xsl:text><xsl:value-of select="$endPtText"/> <xsl:text>
</xsl:text>
    </xsl:template>

    <xsl:template match="text()" />
</xsl:transform>

产地:

Point2 0 1
Point3 1 1
Point4 1 0
Point1 0 0

从:

<root>
  <Points>
    <Point name="Point1">0 0</Point>
    <Point name="Point2">0 1</Point>
    <Point name="Point3">1 1</Point>
    <Point name="Point4">1 0</Point>
  </Points>

  <Shape>
    <Line name="Line1">
        <Start>0 0</Start>
        <End>0 1</End>
    </Line>
    <Line name="Line2">
        <Start>0 1</Start>
        <End>1 1</End>
    </Line>
    <Line name="Line3">
        <Start>1 1</Start>
        <End>1 0</End>
    </Line>
    <Line name="Line4">
        <Start>1 0</Start>
        <End>0 0</End>
    </Line>
  </Shape>
</root>        

XSLTransform

请注意,如果您有两个相同的Point文本节点,则此操作无效,如果您没有与Point节点对应的End节点工作。