我有以下示例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>
我认为选择条件不正确。能不能让我知道什么是正确的条件。
答案 0 :(得分:3)
要确定属性是否存在,只需在元素为最新时使用not()
。
我会颠倒逻辑,即首先移动not present
:
<xsl:when test="not(attr[@name='pageheight'])">
... not present, default it
将检测该行是否没有attr
的{{1}}元素。
修改强>
您无法在此类分支中分配@name attribute
- 它将超出<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>
答案 1 :(得分:3)
您可能希望像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>
或者,如果你正在使用XSLT 2.0,你可以非常简洁地使用序列惯用法来表示默认值:
<xsl:variable name="height"
select="(attr[@name='pageheight'], 0)[1]"/>