比较xml节点并通过xslt:for-each选择

时间:2018-01-24 14:38:46

标签: xml xslt

我想通过将它们与颜色进行比较来选择Xml文档中的图像。 position()不使用,因为图像链接混合顺序。 如果我知道for-each循环在循环中有多少次,但我找不到它

源XML文档:

<?xml version="1.0" encoding="UTF-8" ?>
<products>
    <product>
        <ws_code>61W9232-MZ</ws_code>
        <images>
            <img_item type_name="BLACK">black-1.jpg</img_item>
            <img_item type_name="BLACK">black-2.jpg</img_item>
            <img_item type_name="BLUE">blue-1.jpg</img_item>
            <img_item type_name="BLACK">black-3.jpg</img_item>
            <img_item type_name="BLACK">black-4.jpg</img_item>
            <img_item type_name="NAVY">navy-1.jpg</img_item>
            <img_item type_name="NAVY">navy-2.jpg</img_item>
            <img_item type_name="RED">red-1.jpg</img_item>
            <img_item type_name="NAVY">navy-3.jpg</img_item>
            <img_item type_name="NAVY">navy-4.jpg</img_item>
            <img_item type_name="RED">red-2.jpg</img_item>
            <img_item type_name="BLUE">blue-2.jpg</img_item>
            <img_item type_name="">empty</img_item>
        </images>
        <subproducts>
            <subproduct>
                <code>6675</code>
                <color><![CDATA[BLACK]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6676</code>
                <color><![CDATA[BLACK]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6677</code>
                <color><![CDATA[NAVY]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6678</code>
                <color><![CDATA[NAVY]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6679</code>
                <color><![CDATA[BLUE]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6680</code>
                <color><![CDATA[BLUE]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6681</code>
                <color><![CDATA[RED]]></color>
                <stock>3</stock>
            </subproduct>
            <subproduct>
                <code>6682</code>
                <color><![CDATA[RED]]></color>
                <stock>3</stock>
            </subproduct>   
        </subproducts>
    </product>
</products>

XSLT文件:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="maxEventNum" select="0"/>

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

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

    <xsl:template match="/products/product/subproducts/subproduct">
        <xsl:if test="stock &gt; $maxEventNum">

            <product>

                <xsl:variable name="test">
                    <xsl:value-of select="color"/>
                </xsl:variable>

                <code><xsl:value-of select="code"/></code>-
                <color><xsl:value-of select="color"/></color>-
                <stock><xsl:value-of select="stock"/></stock>-
                <modelCode><xsl:value-of select="../../ws_code"/></modelCode>-

                <images>
                    <xsl:for-each select="../../images/img_item">
                        <xsl:if test="@type_name = $test">
                            <image><xsl:value-of select="."/></image>
                        </xsl:if>
                    </xsl:for-each>
                </images>
            </product>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

结果XML文档:

<?xml version="1.0" encoding="utf-8"?>
<products>
    <product>
        <code>6675</code>
        <color>BLACK</color>
        <stock>3</stock>
        <modelCode>61W9232-MZ</modelCode>
        <image>black-1.jpg</image>
        <image>black-2.jpg</image>
        <image>black-3.jpg</image>
        <image>black-4.jpg</image>
    </product>
    <product>
        .
        .
        .
    </product>
</products>

我需要这个XML文档:

<?xml version="1.0" encoding="utf-8"?>
<products>
    <product>
        <code>6675</code>
        <color>BLACK</color>
        <stock>3</stock>
        <modelCode>61W9232-MZ</modelCode>
        <image1>black-1.jpg</image1>
        <image2>black-2.jpg</image2>
        <image3>black-3.jpg</image3>
        <image4>black-4.jpg</image4>
    </product>
    <product>
        .
        .
        .
    </product>
</products>

4 个答案:

答案 0 :(得分:1)

for-each循环更改为

<images>
  <xsl:for-each select="../../images/img_item">
    <xsl:if test="@type_name = $test">
      <xsl:element name="{concat('image',position())}">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:if>
  </xsl:for-each>
</images>

这会将当前位置追加到基本元素名称image

答案 1 :(得分:0)

当我使用此代码时

<image1>black-1</image1>
<image2>black-2</image2>
<image4>black-3</image4>
<image5>black-4</image5>

蓝色是黑色,image3是跳跃。

<img_item type_name="BLACK">black-1</img_item>
<img_item type_name="BLACK">black-2</img_item>
<img_item type_name="BLUE">blue-1</img_item>
<img_item type_name="BLACK">black-3</img_item>
<img_item type_name="BLACK">black-4</img_item>

答案 2 :(得分:0)

我正在尝试使用此代码,但我无法更改变量的值。

<xsl:variable name="a">1</xsl:variable>
<xsl:for-each select="../../images/img_item">
<xsl:if test="@type_name = $test">
    <xsl:if test="$a=1">
        <xsl:element name="image1">
            <xsl:value-of select="."/>
        </xsl:element>
    <xsl:variable name="a">2</xsl:variable>
    </xsl:if>
    <xsl:if test="$a=2">
        <xsl:element name="image2">
            <xsl:value-of select="."/>
        </xsl:element>
    <xsl:variable name="a">3</xsl:variable>
    </xsl:if>
    <xsl:if test="$a=3">
        <xsl:element name="image3">
            <xsl:value-of select="."/>
        </xsl:element>
    <xsl:variable name="a">4</xsl:variable>
    </xsl:if>
    <xsl:if test="$a=4">
        <xsl:element name="image4">
            <xsl:value-of select="."/>
        </xsl:element>
    <xsl:variable name="a">5</xsl:variable>
    </xsl:if>
</xsl:if>

答案 3 :(得分:0)

重新考虑position(),它相对于<xsl:for-each>映射中的项而不是for-each中的项,而不是树中的原始节点位置。

与@ zx485的生成元素名称的答案类似,请考虑此调整后的XSLT脚本,不使用标识转换或<xsl:if>,并使用带有缩进和条带空间的ancestor::*进行漂亮的打印输出。< / p>

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

  <xsl:template match="/products/product">
    <products>
      <xsl:apply-templates select="subproducts"/>
    </products>
  </xsl:template>

  <xsl:template match="subproducts">
    <xsl:apply-templates select="subproduct[stock &gt; $maxEventNum]"/>
  </xsl:template>

  <xsl:template match="subproduct">
    <xsl:variable name="curr_color" select="color"/>
    <product>
      <xsl:copy-of select="*"/>
      <modelCode>
        <xsl:value-of select="ancestor::product/ws_code"/>
      </modelCode>
      <xsl:for-each select="ancestor::product/images/img_item[@type_name=$curr_color]">
        <xsl:element name="{concat('image', position())}">
          <xsl:value-of select="."/>
        </xsl:element>
      </xsl:for-each>
    </product>
  </xsl:template>

</xsl:stylesheet>