Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 在XSLT中使用If-Else_Xml_Xslt - Fatal编程技术网

Xml 在XSLT中使用If-Else

Xml 在XSLT中使用If-Else,xml,xslt,Xml,Xslt,如果条件匹配,我需要选择一个节点。我对XSLT一无所知,试图寻找答案,但找不到适合我的解决方案。 当有AddressType=Personal时,我想选择一个地址,如果没有AddressType=Personal,请检查“Second”,如果没有,请检查“Office”。 一个正常的If-Else。 我尝试了和,如果XML文件中只存在一种类型的AddressType,这可能会起作用。在我的例子中,XML文件中最多可以有11个地址类型(随机顺序),我只能传递一个 这看起来像我的源XML: <

如果条件匹配,我需要选择一个节点。我对XSLT一无所知,试图寻找答案,但找不到适合我的解决方案。 当有AddressType=Personal时,我想选择一个地址,如果没有AddressType=Personal,请检查“Second”,如果没有,请检查“Office”。 一个正常的If-Else。 我尝试了和,如果XML文件中只存在一种类型的AddressType,这可能会起作用。在我的例子中,XML文件中最多可以有11个地址类型(随机顺序),我只能传递一个

这看起来像我的源XML:

<Person>
<address>
<street></street
<number></number>
<City></City>
<AddressType>Personal</AddressType>
</address>
<address>
<street></street
<number></number>
<City></City>
<AddressType>Second</AddressType>
</address>
<address>
<street></street
<number></number>
<City></City>
<AddressType>Office</AddressType>
</address>
</Person>


您可以使用xsl:choose:

<xsl:choose>
    <xsl:when test"some condition">
        Statement...
    </xsl:when>
    <xsl:when test="some other condition">
        Statement...
    </xsl:when>
    <xsl:otherwise>
        Default...
    </xsl:otherwise>
</xsl:choose>

陈述
陈述
违约
您需要使用


另一个选项是使用模板匹配来获得所需的案例,而不是在xsl:choose中嵌套所有内容。以这个XSLT为例

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="Person[address/AddressType='Personal']" priority="3">
      Match Personal
   </xsl:template>

   <xsl:template match="Person[address/AddressType='Second']" priority="2">
      Match Second
   </xsl:template>

   <xsl:template match="Person[address/AddressType='Office']" priority="1">
      Match Office
   </xsl:template>

   <xsl:template match="Person">
      Match None
   </xsl:template>
</xsl:stylesheet>

匹配个人
比赛第二名
赛会办公室
不匹配
请注意,具有更特定模式的模板优先于没有模式的模板(这就是为什么除非任何其他模板不匹配,否则不会调用最后一个“Person”模板。对于其他模板,如果所有三个模板都匹配,则优先级属性越高。因此“Personal”即使存在其他属性,也将始终选择


(如果没有一个模板具有priority属性,那么在这种情况下将选择最后一个匹配的属性)。

在XSLT 1.0中,有一种简单的方法可以做到这一点:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pAddressTypes" select="'PersonalSecondOffice'"/>
 <xsl:template match="/*">
     <xsl:apply-templates select="address">
       <xsl:sort select=
         "string-length(substring-before($pAddressTypes, AddressType))"/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="address">
  <xsl:if test="position() = 1">
    <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

有点不清楚您的规则是什么。您是否只想筛选
地址
中包含
个人
办公室
,还是需要根据
地址类型
自定义输出?用户1292411:您可能有兴趣找到一个更简短的sol比当前接受的解决方案更简单。根本不需要使用
xsl:choose
。接受的解决方案的大小将随着选项的数量成比例增长。有一种更简单、更短的解决方案,它的大小是固定的,而与选项的数量无关。:)我尝试了这个方法,似乎有效。因此,第一个“when”比下一个等具有优先级……这是否正确?根本不需要使用
xsl:choose
。此解决方案将随着选项数量的增加而成比例增长。有一种更简单、更短的解决方案,它的大小是固定的,与options.thx的数量无关。我试图在biztalk项目中实现这一点,但不断出现错误,可能是由于biztalk中实际架构的复杂性。我在when中使用了choose,但稍后将尝试此解决方案。我是否遗漏了某些内容,或者pAddressTypes参数是否应设置为“Office,Second,Personal”之类的内容,即增加优先级顺序,以便按字符串长度排序获得最高优先级的地址?很好的技巧-我想到了某种地图,但你的方法更简单。@Kevan:排序是递增的——这意味着在
“PersonalSecondOffice”
“PersonalSecondOffice”
中,“Personal”将排在第一位——因此它具有最高的优先级。Duh我没有发现办公室里的单引号
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pAddressTypes" select="'PersonalSecondOffice'"/>
 <xsl:template match="/*">
     <xsl:apply-templates select="address">
       <xsl:sort select=
         "string-length(substring-before($pAddressTypes, AddressType))"/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="address">
  <xsl:if test="position() = 1">
    <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>
<Person>
    <address>
        <street></street>
        <number></number>
        <City></City>
        <AddressType>Office</AddressType>
    </address>
    <address>
        <street></street>
        <number></number>
        <City></City>
        <AddressType>Personal</AddressType>
    </address>
    <address>
        <street></street>
        <number></number>
        <City></City>
        <AddressType>Second</AddressType>
    </address>
</Person>
<address>
   <street/>
   <number/>
   <City/>
   <AddressType>Personal</AddressType>
</address>