【问题标题】:XSLT: How to select siblings with a conditionXSLT:如何选择具有条件的兄弟姐妹
【发布时间】:2018-11-15 16:11:53
【问题描述】:

我有以下 XML:

    <?xml version="1.0" encoding="UTF-8"?>
<thesaurus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <term id="01">
                <name>
            <value>green</value>
        </name>
        <info>
            <ref rid="12" obj-type="Building" />
        </info>
        <info>
            <ref rid="13" obj-type="House" />
        </info>
        <info>
            <ref rid="14" obj-type="Apartment"/>
        </info>
    </term>
    <term id="02">
                <name>
            <value>blue</value>
        </name>
        <info>
            <ref rid="24" obj-type="Unknown"/>
        </info>
        <info>
            <ref rid="26" obj-type="Unknown"/>
        </info>
        <info>
            <ref rid="29" obj-type="Unknown"/>
        </info>
    </term>
    <term id="03">
        <name>
            <value>yellow</value>
        </name>
    </term>
    <term id="04">
        <name>
            <value>red</value>
        </name>
        <info>
            <ref rid="40" obj-type="Hotel"/>
        </info>
        <info>
            <ref rid="41" obj-type="Building"/>
        </info>
        <info>
            <ref rid="43" obj-type="House"/>
        </info>
    </term>
       <term id="05">
        <name>
            <value>purple</value>
        </name>
    </term>
    <term id="06">
        <name>
            <value>magenta</value>
        </name>

        <info>
            <ref rid="60" obj-type="Building"/>
        </info>
        <info>
            <ref rid="62" obj-type="Unknown"/>
        </info>
        <info>
            <ref rid="64" obj-type="House"/>
        </info>
    </term>
</thesaurus>

我想要的是这个:

1) 选择所有没有&lt;info&gt; 标签的&lt;term&gt; 标签。这是 已经使用第一个应用模板完成: select="term[not(info)]" 在下面的 XSLT 中。

2) 当&lt;ref&gt; 标签包含一个&lt;term&gt; 标签时,选择所有标签 obj-type="Unknown"单独或多次,但如果 它被obj-types 包围,其值不同于“Unknown” (如建筑物或房屋)。

*** 在 &lt;info&gt; 标记内,当 obj-type 兄弟姐妹具有其他值时, &lt;term&gt; 标签至少需要一个“未知”值 被选中。


如果 XSLT 运行良好,选择的标签将是:

02、03、05

地点:

01 不会被选中,因为它包含 &lt;info&gt; 标签,并且这些标签都没有 obj-type='Unknown'

02 将被选中,因为 'Unknown' 存在三个多重值,并且 没有与“未知”不同的其他值

03 将被选中,因为它不包含&lt;info&gt; 标签

04 将不会被选中,因为它包含 &lt;info&gt; 标记,其 obj-type 值不同于“未知”。

05 将被选中,因为没有信息标签。

06 不会被选中,因为虽然只有一个值 'Unknown', 所有其他 &lt;ref&gt; 兄弟姐妹的值 obj-type 不同于“未知”。

*** 记住:在&lt;info&gt; 标记内,当obj-type 有其他值的兄弟姐妹时,它至少需要一个值 'Unknown' 表示&lt;term&gt; 标签不会被选中。


我正在使用下面的 XSLT。使用第一个 apply-templates 我可以选择所有没有&lt;info&gt; 标签的标签。

使用第二个apply-templates,我可以选择所有包含&lt;ref&gt; 标记和obj-type="Unknown"&lt;term&gt; 标记,但我不知道如何告诉XSLT如果有不同值的obj-types,不要选择对应的&lt;term&gt;标签。

我尝试使用 for-each 和条件来遍历所有 &lt;ref&gt; 子代,并检查其中一个兄弟姐妹的值是否不同于“未知”以不选择其 &lt;term&gt; 父代,而是没用。

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

<xsl:template match="/thesaurus">       

     <xsl:apply-templates select="term[not(info)]"/>

     <xsl:apply-templates select="term[info/ref[@obj-type='Unknown']]"/>

</xsl:template>

<xsl:template match="term">

      <xsl:value-of select="@id"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select="name"/>
      <xsl:text>,</xsl:text>
      <xsl:text>&#10;</xsl:text>  

</xsl:template>

<xsl:template match="term[info/ref]">

       <xsl:value-of select="@id"/>
       <xsl:text>,</xsl:text>
       <xsl:value-of select="name"/>
       <xsl:text>,</xsl:text>
       <xsl:text>&#10;</xsl:text>

</xsl:template>

</xsl:stylesheet>

我希望它很清楚。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您可以尝试选择不包含 Unknown 以外的其他内容的术语

    <xsl:apply-templates select="term[not(info/ref[@obj-type!='Unknown'])]"/>
    

    或者在 term[info/ref] 模板中添加 if 语句

    <xsl:template match="term[info/ref]">
        <xsl:if test="not(info/ref[@obj-type!='Unknown'])">
           <xsl:value-of select="@id"/>
           <xsl:text>,</xsl:text>
           <xsl:value-of select="name"/>
           <xsl:text>,</xsl:text>
           <xsl:text>&#10;</xsl:text>
        </xsl:if>
    
    </xsl:template>
    

    【讨论】:

    • 它有效。非常感谢您花时间浏览此代码。我知道事情就是这么简单。我尝试使用 IF,但无法用 XSLT 术语正确构造它。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    相关资源
    最近更新 更多