Как получить конкретное значение из денормализованного XML с помощью XSLT - PullRequest
0 голосов
/ 13 октября 2009

Скажем, у меня есть XML, который выглядит так:

<Items>
  <ItemType1>A</ItemType1>
  <ItemValue1>100</ItemValue1>
  <IteType2>B</ItemType2>
  <ItemValue2>10</ItemValue2>
  <ItemType3>C</ItemType3>
  <ItemValue3>0</ItemValue3>
  <ItemType4>D</ItemType4>
  <ItemValue4>50</ItemValue4>
</Items>

И я заинтересован в получении содержимого ItemValueX, где значение ItemTypeX равно C. В этом случае я должен получить 0 (ItemType3 = C, ItemValue3 = 0)

Мне нужно сделать это в XSLT.

Таким образом, конечный результат может быть что-то вроде:

<ChoosenItem>
  <ItemType>C</ItemType>
  <ItemValue>0</ItemValue>
</ChoosenItem>

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 13 октября 2009

Попробуйте это:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="itemValue">C</xsl:param>
  <xsl:template match="/Items">
    <xsl:apply-templates 
         select="//*[starts-with(name(), 'ItemType') and . = $itemValue]" />
  </xsl:template>

  <xsl:template match="*">
    <ChoosenItem>
      <ItemType><xsl:value-of select="." /></ItemType>
      <ItemValue><xsl:value-of select="following-sibling::*" /></ItemValue>
    </ChoosenItem>
  </xsl:template>

</xsl:stylesheet>

Другой подход, избегая match="*"

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="itemValue">C</xsl:param>
  <xsl:template match="/Items">
      <xsl:call-template name="GetItem">
        <xsl:with-param name="id"
             select="//*[starts-with(name(), 'ItemType') and . = $itemValue]" />
      </xsl:call-template>
  </xsl:template>

  <xsl:template name="GetItem">
    <xsl:param name="id" />
    <ChoosenItem>
      <ItemType><xsl:value-of select="$id" /></ItemType>
      <ItemValue><xsl:value-of select="$id/following-sibling::*" /></ItemValue>
    </ChoosenItem>
  </xsl:template>

</xsl:stylesheet>
2 голосов
/ 13 октября 2009

Это работает, если, конечно, у вас всегда будут совпадать пары ItemType и ItemValue

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <xsl:for-each select="/Items/*">
   <xsl:if test=". = 'D'">
    <xsl:variable name="pos" select="position() + 1"/>
    <ChoosenItem>
     <ItemType><xsl:value-of select="."/></ItemType>
     <ItemValue><xsl:value-of select="/Items/*[$pos]"/></ItemValue>
    </ChoosenItem>
   </xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

Который должен выдавать следующий XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<ChoosenItem>
    <ItemType>D</ItemType>
    <ItemValue>50</ItemValue>
</ChoosenItem>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...