从类似节点中选择一个节点

时间:2014-10-23 21:53:02

标签: xml xslt xpath

我试着搜索但是空了。看起来很简单,但我被困住了。

基本上我有记录说我使用了Muenchian分组,但我只需要选择其他分组。

如下面的情况:我只想要一个具有名称 - 蓝色的ID出现。下面的示例应选择ID为1234的蓝色,并忽略名称=红色的其他ID 1234。与最后一个ID 5555相同。位置可以是随机的。最重要的是,我需要将其放入CSV格式。

当我在ID上应用Muenchian分组时,遇到了试图

的问题

非常感谢任何帮助。

<Table>
<Record>
    <ID>1234</ID>
    <Name>Blue</Name>
    <Status>Available</Status>
    <Number>111111</Number>
</Record>
<Record>
    <ID>1234</ID>
    <Name>Red</Name>
    <Status>Available</Status>
    <Number>212121</Number>
</Record>
<Record>
    <ID>2222</ID>
    <Name>Hazel</Name>
    <Status>Available</Status>
    <Number>4424233</Number>
</Record>
<Record>
    <ID>3333</ID>
    <Name>Purple</Name>
    <Status>Available</Status>
    <Number>23234</Number>
</Record>
<Record>
    <ID>4444</ID>
    <Name>Brown</Name>
    <Status>Available</Status>
    <Number>76567567</Number>
</Record>
<Record>
    <ID>5555</ID>
    <Name>Green</Name>
    <Status>Available</Status>
    <Number>3456356</Number>
</Record>
<Record>
    <ID>5555</ID>
    <Name>Blue</Name>
    <Status>Available</Status>
    <Number>324342</Number>
</Record>

输出应为:

<Table>
<Record>
    <ID>1234</ID>
    <Name>Blue</Name>
    <Status>Available</Status>
    <Number>111111</Number>
</Record>
<Record>
    <ID>2222</ID>
    <Name>Orange</Name>
    <Status>Available</Status>
    <Number>4424233</Number>
</Record>
<Record>
    <ID>3333</ID>
    <Name>Silver</Name>
    <Status>Available</Status>
    <Number>23234</Number>
</Record>
<Record>
    <ID>4444</ID>
    <Name>Blue</Name>
    <Status>Available</Status>
    <Number>76567567</Number>
</Record>
<Record>
    <ID>5555</ID>
    <Name>Blue</Name>
    <Status>Available</Status>
    <Number>3456356</Number>
</Record>

更新:我想方设法使用Muenchian Grouping进行此操作并专门针对此案例工作。但我想知道是否有更好的方法可以解决这个问题,以及Muenchian Grouping是否有效。我遇到Muenchian分组的问题是确定在这种情况下第一次出现或第二次出现分组的阶段。

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Table">
  <xsl:text>IDNumber,Name,Status,Number</xsl:text>
    <xsl:text>&#xa;</xsl:text>
        <xsl:for-each select="Record">
            <xsl:choose>
                <xsl:when test="ID = following-sibling::Record[1]/ID and Name = 'Blue'"> 
                    <xsl:value-of select="ID"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Name"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Status"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Number"/>
                    <xsl:text>&#xa;</xsl:text>
                </xsl:when>
                <xsl:when test="ID = following-sibling::Record[1]/ID and Name != 'Blue' and following-sibling::Record[1]/Name != 'Blue'"> 
                    <xsl:value-of select="ID"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Name"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Status"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Number"/>
                    <xsl:text>&#xa;</xsl:text>
                </xsl:when>
                <xsl:when test="ID = following-sibling::Record[1]/ID and Name !='Blue'"> 
                    <xsl:value-of select="following-sibling::Record[1]/ID"/><xsl:text>,          </xsl:text>
                    <xsl:value-of select="following-sibling::Record[1]/Name"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="following-sibling::Record[1]/Status"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="following-sibling::Record[1]/Number"/>
                    <xsl:text>&#xa;</xsl:text>  
                </xsl:when>
                <xsl:when test="ID != preceding-sibling::Record[1]/ID">
                    <xsl:value-of select="ID"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Name"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Status"/><xsl:text>,</xsl:text>
                    <xsl:value-of select="Number"/>
                    <xsl:text>&#xa;</xsl:text>                          
                </xsl:when>
              </xsl:choose>               
            </xsl:for-each> 
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

如果我理解正确,这应该适合你;

XSLT 1.0

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

<xsl:key name="records-by-id" match="Record" use="ID" />

<xsl:template match="/Table">
    <!-- HEADER -->
    <xsl:text>IDNumber,Name,Status,Number&#10;</xsl:text>
    <!-- FOR EACH DISTINCT ID: -->
    <xsl:for-each select="Record[count(. | key('records-by-id', ID)[1]) = 1]">
        <!-- TAKE THE RECORDS IN CURRENT GROUP ... -->
        <xsl:for-each select="key('records-by-id', ID)">
            <!-- .. SORT THEM BY "BLUENESS" ... -->
            <xsl:sort select="Name='Blue'" data-type="text" order="descending"/>
            <!-- ... AND OUTPUT THE FIRST RECORD IN THE (SORTED) GROUP -->
            <xsl:if test="position()=1">
                <xsl:call-template name="row"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<xsl:template name="row">
    <xsl:for-each select="*">
        <xsl:value-of select="."/>
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,结果为:

IDNumber,Name,Status,Number
1234,Blue,Available,111111
2222,Hazel,Available,4424233
3333,Purple,Available,23234
4444,Brown,Available,76567567
5555,Blue,Available,324342