用于检查节点是否存在的 XSLT 条件



我有下面的示例XML,我想在其中检查节点是否存在。

示例 XML 是

<document>
<item>
    <ID>1000909090</ID>
    <flex>
        <attrGroupMany name="pageinfo">
            <row>
                <attr name="pagelength">10</attr>
                <attr name="pagewidth">20</attr>
                <attr name="pageheight">30</attr>
            </row>
            <row>
                <attr name="pagelength">10</attr>
                <attr name="pagewidth">20</attr>
            </row>
        </attrGroupMany>
    </flex>
</item>
</document>

我正在使用下面的 XSLT,但没有得到转换

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="document">
    <CatalogItem>
        <RelationshipData>
            <xsl:for-each select="item">
                <Relationship>
                    <RelationType>PAGEDETAILSINFO</RelationType>
                    <RelatedItems>
                        <xsl:attribute name="count">
                            <xsl:value-of select="count(flex//attrGroupMany[@name = 'pageinfo']/row)"/>
                        </xsl:attribute>
                        <xsl:for-each select="flex//attrGroupMany[@name = 'pageinfo']/row">
                            <xsl:choose>
                                <xsl:when test="not(string-length(attr[@name = 'pageheight'] )) = 0">
                                    <xsl:variable name="height" select="attr[@name='pageheight']"/>
                                </xsl:when>                                                         
                                <xsl:otherwise>
                                    <xsl:variable name="height" select="'0'"/>
                                </xsl:otherwise>
                            </xsl:choose> 
                            <RelatedItem>
                                <xsl:attribute name="referenceKey">
                                    <xsl:value-of select="concat('Food_And_Bev_Allergen_MVL','-',ancestor::item/ID,'-',$height)"/>
                                </xsl:attribute>
                            </RelatedItem>
                        </xsl:for-each>
                    </RelatedItems>
                </Relationship>
            </xsl:for-each>
        </RelationshipData>
    </CatalogItem>
</xsl:template>
</xsl:stylesheet>

我认为选择条件不正确。 你能告诉我正确的条件是什么吗?

您可能希望按照 Stuart 的建议调整默认逻辑,但主要问题是必须更正height变量范围

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="document">
    <CatalogItem>
      <RelationshipData>
        <xsl:for-each select="item">
          <Relationship>
            <RelationType>PAGEDETAILSINFO</RelationType>
            <RelatedItems>
              <xsl:attribute name="count">
                <xsl:value-of select="count(flex//attrGroupMany[@name = 'pageinfo']/row)"/>
              </xsl:attribute>
              <xsl:for-each select="flex//attrGroupMany[@name = 'pageinfo']/row">
                <xsl:variable name="height">
                  <xsl:choose>
                    <xsl:when test="not(attr[@name = 'pageheight'])">                                       
                      <xsl:value-of select="'0'"/>
                    </xsl:when>                                                         
                    <xsl:otherwise>                                     
                      <xsl:value-of select="attr[@name='pageheight']"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:variable>
                <RelatedItem>
                  <xsl:attribute name="referenceKey">
                    <xsl:value-of select="concat('Food_And_Bev_Allergen_MVL','-',ancestor::item/ID,'-',$height)"/>
                  </xsl:attribute>
                </RelatedItem>
              </xsl:for-each>
            </RelatedItems>
          </Relationship>
        </xsl:for-each>
      </RelationshipData>
    </CatalogItem>
  </xsl:template>
</xsl:stylesheet>

进行上述更改后,此输入 XML:

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <item>
    <ID>1000909090</ID>
    <flex>
      <attrGroupMany name="pageinfo">
        <row>
          <attr name="pagelength">10</attr>
          <attr name="pagewidth">20</attr>
          <attr name="pageheight">30</attr>
        </row>
        <row>
          <attr name="pagelength">10</attr>
          <attr name="pagewidth">20</attr>
        </row>
      </attrGroupMany>
    </flex>
  </item>
</document>

将转换为此输出 XML:

<?xml version="1.0" encoding="UTF-8"?>
<CatalogItem>
   <RelationshipData>
      <Relationship>
         <RelationType>PAGEDETAILSINFO</RelationType>
         <RelatedItems count="2">
            <RelatedItem referenceKey="Food_And_Bev_Allergen_MVL-1000909090-30"/>
            <RelatedItem referenceKey="Food_And_Bev_Allergen_MVL-1000909090-0"/>
         </RelatedItems>
      </Relationship>
   </RelationshipData>
</CatalogItem>

编辑

请注意,以下是默认逻辑的更自然的表达:

            <xsl:variable name="height">
              <xsl:choose>
                <xsl:when test="attr[@name = 'pageheight']">
                  <xsl:value-of select="attr[@name='pageheight']"/>
                </xsl:when>
                <xsl:otherwise>0</xsl:otherwise>
              </xsl:choose>
            </xsl:variable>

编辑 2

或者,如果您使用的是 XSLT 2.0,则可以非常简洁地使用默认值的序列习惯用法:

            <xsl:variable name="height" 
                          select="(attr[@name='pageheight'], 0)[1]"/>

要确定该属性是否存在,只需在元素为当前元素时使用not()

我会颠倒逻辑,即首先移动not present

<xsl:when test="not(attr[@name='pageheight'])">
  ... not present, default it 

将检测该行是否没有带有@name attributeattr元素。

编辑

您不能在这样的分支中分配<xsl:variable> - 它将超出xsl:choose范围内的范围。切换到:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="document">
    <CatalogItem>
      <RelationshipData>
        <xsl:for-each select="item">
          <Relationship>
            <RelationType>PAGEDETAILSINFO</RelationType>
            <RelatedItems>
              <xsl:attribute name="count">
                <xsl:value-of select="count(flex//attrGroupMany[@name = 'pageinfo']/row)"/>
              </xsl:attribute>
              <xsl:for-each select="flex//attrGroupMany[@name = 'pageinfo']/row">
                <xsl:variable name="height">
                  <xsl:choose>
                    <xsl:when test="not(attr[@name = 'pageheight'])">
                      <xsl:text>0</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="attr[@name='pageheight']"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:variable>
                <RelatedItem>
                  <xsl:attribute name="referenceKey">
                    <xsl:value-of select="concat('Food_And_Bev_Allergen_MVL','-',ancestor::item/ID,'-',$height)"/>
                  </xsl:attribute>
                </RelatedItem>
              </xsl:for-each>
            </RelatedItems>
          </Relationship>
        </xsl:for-each>
      </RelationshipData>
    </CatalogItem>
  </xsl:template>
</xsl:stylesheet>

返回的代码段包括:

  <RelatedItems count="2">
    <RelatedItem referenceKey="Food_And_Bev_Allergen_MVL-1000909090-30" />
    <RelatedItem referenceKey="Food_And_Bev_Allergen_MVL-1000909090-0" />
  </RelatedItems>

相关内容

  • 没有找到相关文章