XSLT 2.0 - 保留默认元素,删除重复的兄弟元素,按属性过滤不必要的条目 [英] XSLT 2.0 - Keep default element, remove duplicate siblings, filter unnecessary entries by attribute

查看:21
本文介绍了XSLT 2.0 - 保留默认元素,删除重复的兄弟元素,按属性过滤不必要的条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 XSLT 2.0.

Using XSLT 2.0.

我需要过滤所有具有 @xml:lang 属性的元素,其中该属性的值不在我定义的可能值列表中.Ex 允许值:x-default,en,en-US,en-GB

I need to filter all elements that have attribute @xml:lang where the attribute's values are not in a list of possible values I define. Ex allowable values: x-default,en,en-US,en-GB

当在任何元素上检测到 @xml:lang 时,如果 x-default 存在,则任何与 @xml:lang 相同类型的兄弟元素x-default 以外的 值应与x-default 元素的文本值进行比较,如果元素文本值相同,则将其删除.换句话说,根据元素的文本值比较,应该删除 @xml:lang="x-default" 的任何同级重复项.

When @xml:lang is detected on any element, and if x-default exists, then any sibling element of same type with @xml:lang value other than x-default should be compared to the element's text value of x-default, and if same element text value, be removed. To say that another way, any sibling duplicates of @xml:lang="x-default" should be removed, based on the element's text value comparison.

如果可以对重复的顺序进行排序,则奖励积分,例如始终选择 x-default(如果存在),然后是第二层(enfr, ru),然后是第三层(en-EN, en-GB, fr-FR, ru-RU),其中删除第一层的第二层副本,并将第三层与第二层(如果存在)进行比较,否则为第一层层,以便第三层如果重复也会被删除.这需要动态处理,因为有许多可能的语言.

Bonus points if it's possible to rank the order of duplicates, such that x-default is always chosen (if exists), followed by a second tier (en, fr, ru), followed by a third tier (en-EN, en-GB, fr-FR, ru-RU), where the second tier duplicates of the first tier are removed, and the third tier is compared to second tier (if exists), or else the first tier, so that the third tier is also removed if duplicate. This would need to be handled dynamically, as there are many possible languages.

还应该考虑的一种特殊情况是,第一层 (x-default) 具有 some value,第二层 (en) 有 some value,第三层 (en-US) 有 some value.在这种情况下,没有要删除的重复项,因为第二层存在而第三层不匹配.

A special case that should be also considered, is a situation where first tier (x-default) has some value, second tier (en) has some valuation, third tier (en-US) has some value. In this situation, there's no duplicate to remove, as the second tier exists and the third tier does not match it.

我当前的 XSLT(不尝试删除重复项,因为我还没有找到可靠的解决方案,而且我的任何尝试都失败了).这不是我理想的 XSLT,它只是我目前所知道的最好的构建,它能够过滤数据集.我的程序员希望看到所有 or 都更改为数组值检查,以便可以更干净地管理值,但我不确定这在 XSLT 中是否可行:

My current XSLT (doesn't attempt removing duplicates, as I've not found a sure-fire solution yet, and any attempts on my part have failed miserably). This is not my ideal XSLT, it's just the best I know to build currently, and it's able to filter down the data set. The programmer in me would like to see all the or's changed to an array-value check so the values can be managed more cleanly, but I'm not sure if that's doable in XSLT:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://some.namespace/uri">

<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<!-- Select everything except comment/processing instruction nodes -->
<xsl:template match="attribute()|element()|text()">
    <xsl:copy>
        <xsl:apply-templates select="attribute()|element()|text()"/>
    </xsl:copy>
</xsl:template>

<!-- Remove categories & assignments not in our whitelist -->
<xsl:template match="//*[@category-id and not(@category-id='root'
    or @category-id='men' or @category-id='men_clothing' or @category-id='men_clothing_tshirts'
    or @category-id='sales' or @category-id='sales_men' or @category-id='sales_men_tees'
    or @category-id='sales' or @category-id='sales_women' or @category-id='sales_women_tanks-teeshirts'
    or @category-id='clothing' or @category-id='clothing_teeshirts'
    or @category-id='kids' or @category-id='kids_0816'
    or @category-id='men' or @category-id='men_shoes' or @category-id='men_shoes_skate'
    or @category-id='sales' or @category-id='sales_men' or @category-id='sales _men_shoes'
    )]"/>

<!-- Remove locales not default or in whitelist -->
<xsl:template match="//*[@xml:lang and not(@xml:lang='x-default' or @xml:lang='en' or @xml:lang='en-US' or @xml:lang='en-CA' or @xml:lang='en-GB' or @xml:lang='fr' or @xml:lang='fr-FR' or @xml:lang='ru' or @xml:lang='ru-RU')]"/>

<!-- Remove empty nodes -->
<xsl:template match="*[not(normalize-space()) and not(.//@*)]"/>

</xsl:stylesheet>

下面的示例数据集.在实际数据集中,还有 许多 个元素,因此再次删除重复 @xml:lang 条目的逻辑不能硬编码到您可能推断出的 XPath,而是对相邻分组的相同类型数据组进行操作.

Example dataset below. In a real dataset, there are many more elements, so again the logic to remove duplicate @xml:lang entries must not be hard-coded to the XPath you might deduce, but rather operate on groups of same-type data, grouped adjacent.

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://some.namespace/uri" catalog-id="catalog-products">
  <category category-id="sales_women">
    <display-name xml:lang="x-default"><![CDATA[Women's Sales]]></display-name>
    <display-name xml:lang="en"><![CDATA[Sales for Women]]></display-name>
    <display-name xml:lang="en-US"><![CDATA[Women's Sales]]></display-name>
  </category>
  <product product-id="111111111">
    <display-name xml:lang="x-default"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="de"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="en"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="en-US"><![CDATA[Aurora Fleece]]></display-name>
    <display-name xml:lang="es"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="fr"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="ru"><![CDATA[Aurora]]></display-name>
    <short-description xml:lang="de"><![CDATA[Aurora - Fleece-Top für Damen]]></short-description>
    <short-description xml:lang="en"><![CDATA[Aurora - Sweatshirt for women]]></short-description>
    <short-description xml:lang="x-default"><![CDATA[Aurora - Sweatshirt for women]]></short-description>
    <short-description xml:lang="en-US"><![CDATA[Snow Fleece & Softshells - Aurora Fleece]]></short-description>
    <short-description xml:lang="es"><![CDATA[Aurora - Top polar de mujer]]></short-description>
    <short-description xml:lang="fr"><![CDATA[Aurora - haut en polaire femme]]></short-description>
    <short-description xml:lang="ru"><![CDATA[Свитшот SomeBrand для девушек]]></short-description>
    <long-description xml:lang="de"><![CDATA[<p class="productLongDescriptionTitle"></p><p class="productLongDescriptionSubTitle">Composition</p><p>100 % Polyester</p>]]></long-description>
    <long-description xml:lang="en"><![CDATA[<p class="productLongDescriptionTitle"></p><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester</p>]]></long-description>
    <long-description xml:lang="x-default"><![CDATA[<p class="productLongDescriptionTitle"><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester</p>]]></long-description>
    <long-description xml:lang="en-US"><![CDATA[<p class="productLongDescriptionTitle"></p><p>The stretchy, polar fleece Aurora zip-up shields you from the elements with street-savvy style to have you standing out on the slopes and the sidewalk. Designed with a tailored fit, tech details include zippered hand warmer pockets, a lyrca binding finish, a chest pocket, flatlock seams for smooth comfort, and ergonomic seams for support. Imported. 100% polyester polar fleece.</p><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester
Polar Fleece</p>]]></long-description>
    <long-description xml:lang="es"><![CDATA[<p class="productLongDescriptionSubTitle">Composition</p><p>100% poliéster</p>]]></long-description>
    <long-description xml:lang="fr"><![CDATA[<p class="productLongDescriptionSubTitle">Composition</p><p>100 % polyester</p>]]></long-description>
    <long-description xml:lang="ru"><![CDATA[<p>Женский свитшот SomeBrand из зимней коллекции одежды 2014. Характеристики: влаговыводящая технология DRY-FLIGHT, эластичный флис из полиэстера (250 г), теплые карманы на молнии для ладошек.</p><p class="productLongDescriptionSubTitle"></p><p>100% полиэстер</p>]]></long-description>
    <!-- === PICTURES === -->
    <images>
      <image-group view-type="hi-res">
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_frt1.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_frt2.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_bck1.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
      </image-group>
    </images>
  </product>
</catalog>

Ex 所需的数据集:

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://some.namespace/uri" catalog-id="catalog-products">
  <category category-id="sales_women">
    <display-name xml:lang="x-default"><![CDATA[Women's Sales]]></display-name>
    <display-name xml:lang="en"><![CDATA[Sales for Women]]></display-name>
    <display-name xml:lang="en-US"><![CDATA[Women's Sales]]></display-name>
  </category>
  <product product-id="111111111">
    <display-name xml:lang="x-default"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="en-US"><![CDATA[Aurora Fleece]]></display-name>
    <short-description xml:lang="de"><![CDATA[Aurora - Fleece-Top für Damen]]></short-description>
    <short-description xml:lang="x-default"><![CDATA[Aurora - Sweatshirt for women]]></short-description>
    <short-description xml:lang="en-US"><![CDATA[Snow Fleece & Softshells - Aurora Fleece]]></short-description>
    <short-description xml:lang="es"><![CDATA[Aurora - Top polar de mujer]]></short-description>
    <short-description xml:lang="fr"><![CDATA[Aurora - haut en polaire femme]]></short-description>
    <short-description xml:lang="ru"><![CDATA[Свитшот SomeBrand для девушек]]></short-description>
    <long-description xml:lang="x-default"><![CDATA[<p class="productLongDescriptionTitle"><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester</p>]]></long-description>
    <long-description xml:lang="en-US"><![CDATA[<p class="productLongDescriptionTitle"></p><p>The stretchy, polar fleece Aurora zip-up shields you from the elements with street-savvy style to have you standing out on the slopes and the sidewalk. Designed with a tailored fit, tech details include zippered hand warmer pockets, a lyrca binding finish, a chest pocket, flatlock seams for smooth comfort, and ergonomic seams for support. Imported. 100% polyester polar fleece.</p><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester
Polar Fleece</p>]]></long-description>
    <long-description xml:lang="es"><![CDATA[<p class="productLongDescriptionSubTitle">Composition</p><p>100% poliéster</p>]]></long-description>
    <long-description xml:lang="ru"><![CDATA[<p>Женский свитшот SomeBrand из зимней коллекции одежды 2014. Характеристики: влаговыводящая технология DRY-FLIGHT, эластичный флис из полиэстера (250 г), теплые карманы на молнии для ладошек.</p><p class="productLongDescriptionSubTitle"></p><p>100% полиэстер</p>]]></long-description>
    <!-- === PICTURES === -->
    <images>
      <image-group view-type="hi-res">
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_frt1.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_frt2.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_bck1.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
      </image-group>
    </images>
  </product>
</catalog>

推荐答案

您可以使用以下内容作为起点.也就是说,我相信它满足您的主要要求:

Here's something you could use as your starting point. That is, I believe it satisfies your primary request:

当在任何元素上检测到 @xml:lang 时,如果 x-default 存在,然后任何具有 @xml:lang 值的相同类型的同级元素,而不是x-default 应该与元素的文本值 x-default 进行比较,如果元素文本值相同,则删除.

When @xml:lang is detected on any element, and if x-default exists, then any sibling element of same type with @xml:lang value other than x-default should be compared to the element's text value of x-default, and if same element text value, be removed.

更清楚地说,它删除了满足所有这三个条件的任何元素:

To state it more clearly, it removes any element that satisfies all of these three conditions:

  1. 它有一个 xml:lang 属性;
  2. xml:lang 属性不是x-default";
  3. 元素的值等于同名的值,xml:lang 属性为x-default"的兄弟元素.

XSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://some.namespace/uri">

<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="ns1:display-name ns1:short-description ns1:long-description ns1:alt ns1:title"/>

<xsl:key name="default-sibling" match="*[@xml:lang='x-default']" use="concat(generate-id(..), '|', local-name())" />

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

<xsl:template match="*[@xml:lang!='x-default' and .=key('default-sibling', concat(generate-id(..), '|', local-name()))]"/>

</xsl:stylesheet>

应用于您的示例输入,获得以下结果:

Applied to your example input, the following result is obtained:

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://some.namespace/uri" catalog-id="catalog-products">
  <category category-id="sales_women">
    <display-name xml:lang="x-default"><![CDATA[Women's Sales]]></display-name>
    <display-name xml:lang="en"><![CDATA[Sales for Women]]></display-name>
  </category>
  <product product-id="111111111">
    <display-name xml:lang="x-default"><![CDATA[Aurora]]></display-name>
    <display-name xml:lang="en-US"><![CDATA[Aurora Fleece]]></display-name>
    <short-description xml:lang="de"><![CDATA[Aurora - Fleece-Top für Damen]]></short-description>
    <short-description xml:lang="x-default"><![CDATA[Aurora - Sweatshirt for women]]></short-description>
    <short-description xml:lang="en-US"><![CDATA[Snow Fleece & Softshells - Aurora Fleece]]></short-description>
    <short-description xml:lang="es"><![CDATA[Aurora - Top polar de mujer]]></short-description>
    <short-description xml:lang="fr"><![CDATA[Aurora - haut en polaire femme]]></short-description>
    <short-description xml:lang="ru"><![CDATA[Свитшот SomeBrand для девушек]]></short-description>
    <long-description xml:lang="de"><![CDATA[<p class="productLongDescriptionTitle"></p><p class="productLongDescriptionSubTitle">Composition</p><p>100 % Polyester</p>]]></long-description>
    <long-description xml:lang="en"><![CDATA[<p class="productLongDescriptionTitle"></p><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester</p>]]></long-description>
    <long-description xml:lang="x-default"><![CDATA[<p class="productLongDescriptionTitle"><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester</p>]]></long-description>
    <long-description xml:lang="en-US"><![CDATA[<p class="productLongDescriptionTitle"></p><p>The stretchy, polar fleece Aurora zip-up shields you from the elements with street-savvy style to have you standing out on the slopes and the sidewalk. Designed with a tailored fit, tech details include zippered hand warmer pockets, a lyrca binding finish, a chest pocket, flatlock seams for smooth comfort, and ergonomic seams for support. Imported. 100% polyester polar fleece.</p><p class="productLongDescriptionSubTitle">Composition</p><p>100% Polyester
Polar Fleece</p>]]></long-description>
    <long-description xml:lang="es"><![CDATA[<p class="productLongDescriptionSubTitle">Composition</p><p>100% poliéster</p>]]></long-description>
    <long-description xml:lang="fr"><![CDATA[<p class="productLongDescriptionSubTitle">Composition</p><p>100 % polyester</p>]]></long-description>
    <long-description xml:lang="ru"><![CDATA[<p>Женский свитшот SomeBrand из зимней коллекции одежды 2014. Характеристики: влаговыводящая технология DRY-FLIGHT, эластичный флис из полиэстера (250 г), теплые карманы на молнии для ладошек.</p><p class="productLongDescriptionSubTitle"></p><p>100% полиэстер</p>]]></long-description>
<!-- === PICTURES === -->
    <images>
      <image-group view-type="hi-res">
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_frt1.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_frt2.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
        <image path="catalog-products/all/default/hi-res/111111111_aurora,v_kpv0_bck1.jpg">
          <alt xml:lang="x-default"><![CDATA[Aurora 111111111]]></alt>
          <title xml:lang="x-default"><![CDATA[Aurora 111111111]]></title>
        </image>
      </image-group>
    </images>
  </product>
</catalog>

我相信您也可以扩展相同的原则来实现您的奖励积分"和特殊情况"(前提是您可以像上述要求一样清楚地说明要求 - 包括共同的优先事项).不过,您可能需要多次通过才能获得全部.

I believe you could extend the same principle to achieve your "bonus points" and the "special case" too (provided you can state the requirements as clearly as the one above - including mutual priorities). You may have to do more than one pass to get them all, though.

我建议您针对基于白名单的过滤提出单独的问题(或搜索以前的答案).

I suggest you ask a separate question (or search previous answers) regarding filtering based on a whitelist.

这篇关于XSLT 2.0 - 保留默认元素,删除重复的兄弟元素,按属性过滤不必要的条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆