2013-04-04 5 views
0

Мой образец xml выглядит ниже: Мне нужно получить различные состояния из xml. Я использую xslt 1.0 в редакторе vs 2010.Получить отличные значения от xml

<?xml version="1.0" encoding="utf-8" ?> 
<states> 
    <node> 
    <value>2</value> 
    <state>DE</state> 
    </node> 
    <node> 
    <value>1</value> 
    <state>DE</state> 
    </node> 
    <node> 
    <value>1</value> 
    <state>NJ</state> 
    </node> 
    <node> 
    <value>1</value> 
    <state>NY</state> 
    </node> 

    <node> 
    <value>1</value> 
    <state>NY</state> 
    </node> 
</states> 

Мой XSLT выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
    xmlns:user="urn:my-scripts"> 

    <xsl:output method="text" indent="yes"/> 

    <xsl:key name="st" match="//states/node/state" use="." /> 

    <xsl:variable name="disst"> 
    <xsl:for-each select="//states/node[contains(value,1)]/state[generate-id()=generate-id(key('st',.)[1])]" > 
     <xsl:choose> 
     <xsl:when test="(position() != 1)"> 
      <xsl:value-of select="concat(', ',.)" disable-output-escaping="yes"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="." disable-output-escaping="yes"/> 
     </xsl:otherwise> 
     </xsl:choose> 

    </xsl:for-each> 


    </xsl:variable> 

    <xsl:template match="/" > 
     <xsl:value-of disable-output-escaping="yes" select="$disst"/> 

    </xsl:template> 
</xsl:stylesheet> 

Выход: DE, Нью-Джерси, Нью-Йорк

Мой выше XML выглядит хорошо для вышеприведенного тест XML.

Если изменить XML, как показано ниже:

<?xml version="1.0" encoding="utf-8" ?> 
<states> 
    <node> 
    <value>2</value> 
    <state>DE</state> 
    </node> 
    <node> 
    <value>1</value> 
    <state>DE</state> 
    </node> 
    <node> 
    <value>1</value> 
    <state>NJ</state> 
    </node> 
    <node> 
    <value>1</value> 
    <state>NY</state> 
    </node> 

    <node> 
    <value>1</value> 
    <state>NY</state> 
    </node> 
</states> 

его в не собирание состояние DE. Может ли кто-нибудь предложить подходящее решение. Спасибо заранее. Мне нужно выяснить различные состояния из xml.

ответ

2

Проблема здесь ваше использование предиката в вашей Muenchian группировки XPath:

[contains(value,1)] 

Это часто делают Muenchian группировка не найти все доступные различных значений. Вместо этого, вы должны добавить предикат к ключу:

<xsl:key name="st" match="//states/node[contains(value, 1)]/state" use="." /> 

В качестве альтернативы, вы можете применить предикат внутри группирования заявление:

<xsl:apply-templates 
    select="//states/node 
       /state[generate-id() = 
         generate-id(key('st',.)[contains(../value, 1)][1])]" /> 

Полный XSLT (с некоторыми усовершенствованиями):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:user="urn:my-scripts"> 
    <xsl:output method="text" indent="yes"/> 

    <xsl:key name="st" match="//states/node/state" use="." /> 
    <xsl:variable name="a" select="1" /> 

    <xsl:variable name="disst"> 
    <xsl:apply-templates 
     select="//states/node 
        /state[generate-id() = 
          generate-id(key('st',.)[contains(../value, $a)][1])]" /> 
    </xsl:variable> 

    <xsl:template match="state"> 
    <xsl:if test="position() > 1"> 
     <xsl:text>,</xsl:text> 
    </xsl:if> 
    <xsl:value-of select ="." disable-output-escaping="yes" /> 
    </xsl:template> 

    <xsl:template match="/" > 
    <xsl:value-of disable-output-escaping="yes" select="$disst"/> 

    </xsl:template> 
</xsl:stylesheet> 

Результат при использовании на вашем примере XML:

DE,NJ,NY 
+0

Если у меня есть сценарий: 1 Blossom

+0

Сделана необходимая модификация выше. – JLRishe

+0

спасибо Рише. – Blossom

Смежные вопросы