首页 > 解决方案 > 根据属性值过滤 XML

问题描述

我有一个 XML 文件,其中包含有关一个或多个“区域”的 html 文本

此文本嵌入在名为“myText”的节点中。

<UrbanDoc myId="abc">
    <myText zone="general">
        <h1>1. General Text</h1>
        <div>blabla</div>
        <ul>
            <li>bullet 1 blabla</li>
            <li>bullet 2 blabla</li>
        </ul>
        <div>more text blabla</div>
    </myText>
    <myText zone="UG,1AU">
        <h1>2. Text related to 2 zones</h1>
        <myText zone="UG">
            <h2>2.1. Text only related to zone UG</h2>
            <div>blabla</div>
            <myText zone="UG,1AU">
                <h2>2.2. Text related to 2 zones</h2>
                <ul>
                    <li>bullet 1 blabla</li>
                    <li>bullet 2 blabla</li>
                </ul>
            </myText>
            <div>more text blabla</div>
        </myText>
    </myText>
    <myText zone="1AU">
        <h1>3. Text related to 1AU</h1>
        <div>blabla</div>
        <ul>
            <li>bullet 1 blabla</li>
            <li>bullet 2 blabla</li>
        </ul>
        <div>more text blabla</div>
    </myText>
    <myText zone="N">
        <h1>4. Text concerning zone N</h1>
        <div>blabla</div>
        <ul>
            <li>bullet 1 blabla</li>
            <li>bullet 2 blabla</li>
        </ul>
        <div>more text blabla</div>
    </myText>
</UrbanDoc>

我想过滤 xml 文件以删除所有不具有包含“1AU”的区域的分支(节点和子节点)。这是我的 xsl 代码:

<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="myText[not(descendant-or-self::myText[contains(@zone,'1AU')])]//*">
</xsl:template>

我得到的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<UrbanDoc myId="abc">
    <myText zone="general">
        
    </myText>
    <myText zone="UG,1AU">
        <h1>2. Text related to 2 zones</h1>
        <myText zone="UG">
            
            </myText>
            <myText zone="UG,1AU">
                <h2>2.2. Text related to 2 zones</h2>
                <ul>
                    <li>bullet 1 blabla</li>
                    <li>bullet 2 blabla</li>
                </ul>
            </myText>
            <div>more text blabla</div>
    </myText>
    <myText zone="1AU">
        <h1>3. Text related to 1AU</h1>
        <div>blabla</div>
        <ul>
            <li>bullet 1 blabla</li>
            <li>bullet 2 blabla</li>
        </ul>
        <div>more text blabla</div>
    </myText>
    <myText zone="N">
        
    </myText>
</UrbanDoc>

我想拥有:

<?xml version="1.0" encoding="UTF-8"?>
<UrbanDoc myId="abc">
    
    <myText zone="UG,1AU">
        <h1>2. Text related to 2 zones</h1>
        
            <myText zone="UG,1AU">
                <h2>2.2. Text related to 2 zones</h2>
                <ul>
                    <li>bullet 1 blabla</li>
                    <li>bullet 2 blabla</li>
                </ul>
            </myText>
            <div>more text blabla</div>
    </myText>
    <myText zone="1AU">
        <h1>3. Text related to 1AU</h1>
        <div>blabla</div>
        <ul>
            <li>bullet 1 blabla</li>
            <li>bullet 2 blabla</li>
        </ul>
        <div>more text blabla</div>
    </myText>

</UrbanDoc>

谢谢您的帮助 !

标签: xsltxpath

解决方案


显然,问题出在我的模板中。

用此代码替换第二个模板有效

<xsl:template match="myText[not(descendant-or-self::myText[contains(@zone,'1AU')])]">
</xsl:template>

推荐阅读