我有下面的示例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 attribute
的attr
元素。
编辑
您不能在这样的分支中分配<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>