如何使用XSLT从非规范化XML获取特定值

时间:2009-10-13 13:58:43

标签: xml xslt

假设我有一个看起来像这样的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>

我有兴趣获取ItemTypeX值为C的ItemValueX的内容。 在这种情况下,我应该得到0(ItemType3 = C,ItemValue3 = 0)

我需要在XSLT中执行此操作。

所以最终结果可能是:

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

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

这是有效的,当然假设你总是有一对ItemTypeItemValue

<?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>

答案 1 :(得分:2)

试试这个:

<?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>