2012-02-06 17 views
0

每个<leg>都记录了行程。旅程按文件顺序记录。一些腿在相同的地方开始和结束(例如,从MA到MA),一些腿去处(例如从MA到CT)。一些关于开始和结束位置的数据丢失。属性中的订单和重复数据

<trip> 
    <leg start="MA" stop="MA" /> 
    <leg start="MA" stop="CT" /> 
    <leg start="NY"   /> 
    <leg      /> 
    <leg start="DE"   /> 
    <leg   stop="DE" /> 
    <leg start="NY" stop="PA" /> 
</trip> 

使用XSLT/XPATH 1.0,我想地方的列表,顺序访问:

<trip> 
    <place>MA</place> 
    <place>CT</place> 
    <place>NY</place> 
    <place>DE</place> 
    <place>NY</place> 
    <place>PA</place> 
</trip> 

编辑:

OK,我想我看到怎么办它:

<xsl:template match="leg" mode="tour"> 
    <xsl:if test="string(@start)"> 
     <place><xsl:value-of select="@start"></place> 
    </xsl:if> 
    <xsl:if test="string(@end)"> 
     <place><xsl:value-of select="@end"></place> 
    </xsl:if> 
</xsl:template> 


<xsl:variable name="rtfPlaces"> 
    <xsl:apply-templates select="trip/leg" mode="tour" /> 
</xsl:variable> 

<xsl:variable name="places" select="exslt:node-set($rtfPlaces)" /> 

<xsl:variable name="uniquePlaces" select="$places/place[1] | $places/place[.!=preceding-sibling::place[1]]" /> 

解决方案:确实处理它在两遍。通过单独书写它们,按需要的顺序获取@start和@end。然后在第二遍中选择唯一值。

这不会让我在输出中的trip元素,但我不认为我真的需要这样做。

它确实需要节点集扩展,但也可以。

如果它可以一次完成,我不知道如何。

+0

如何好...你有什么想问一个问题吗?这不是一个“为我写这段代码”的网站,它是“这是我试过的,它有什么问题?” – 2012-02-06 01:01:17

+0

当我没有把我的个人笨拙带走的时候,我通常会有更友好的回答。我对进攻表示歉意。在这一个,我不知道从哪里开始。我以为我会序列化,然后重复,但由于属性没有按照文档顺序处理,我怎么按顺序交错开始和结束?虽然头疼,但我不舒服,即使首先序列化是正确的策略。我会一直徘徊,回头看看有人向失落的灵魂提供帮助,并在编码失败后编辑帖子。 – JPM 2012-02-06 01:31:02

回答

1

这应该得到它在一通...

XML输入

<trip> 
    <leg start="MA" stop="MA" /> 
    <leg start="MA" stop="CT" /> 
    <leg start="NY"   /> 
    <leg      /> 
    <leg start="DE"   /> 
    <leg   stop="DE" /> 
    <leg start="NY" stop="PA" /> 
</trip> 

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="node()|@*"> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:template> 

    <xsl:template match="trip"> 
    <trip> 
     <xsl:apply-templates/> 
    </trip> 
    </xsl:template> 

    <!--This is so we don't get duplicate entries 
    for both attributes when they are the same.--> 
    <xsl:template match="@stop[.=parent::*/@start]"/> 

    <xsl:template match="@start|@stop"> 
    <xsl:if test="not(parent::leg/preceding-sibling::leg[1][@start = current() or @end = current()])"> 
     <place><xsl:value-of select="."/></place>  
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

XML输出

<trip> 
    <place>MA</place> 
    <place>CT</place> 
    <place>NY</place> 
    <place>DE</place> 
    <place>NY</place> 
    <place>PA</place> 
</trip> 

您还可以添加此模板,以确保100%是@start渐渐@stop前处理:

<xsl:template match="leg"> 
    <xsl:apply-templates select="@start"/> 
    <xsl:apply-templates select="@stop"/> 
    </xsl:template> 
+0

好多了。谢谢!在我的XSLT学习中,我还没有考虑像使用XSLT优先级设置程序来覆盖start = stop。对我来说是好教训。 +1,Q回答。 (如果你想提高原Q值,请做。) – JPM 2012-02-06 15:11:43

+0

非常欢迎。 +1 – 2012-02-06 16:55:49