当前位置: 首页 > 知识库问答 >
问题:

XSLT转换选择具有特定属性值的元素

幸弘扬
2023-03-14

嗨,我有以下XML

<?xml version="1.0" encoding="UTF-8"?>
<catalog catalog-id="Primary">
<product product-id="clothes">
    <items>
        <item item-name="TShirt">Brown</item>
        <item item-name="Pants">Green</item>
        <item item-name="Shirt">White</item>
    </items>
</product>
<product product-id="toys">
    <items>
        <item item-name="Ball">Cyan</item>
        <item item-name="Bat">Green</item>
        <item item-name="Racket">Blue</item>
    </items>
</product>
</catalog>

标准是只复制“item-name”属性值为TShert、Ball或Bat的位置。所以生成的XML应该看起来像

<?xml version="1.0" encoding="UTF-8"?>
<catalog catalog-id="Primary">
<product product-id="clothes">
    <items>
        <item item-name="TShirt">Brown</item>
    </items>
</product>
<product product-id="toys">
    <items>
        <item item-name="Ball">Cyan</item>
        <item item-name="Bat">Green</item>
    </items>
</product>
</catalog>

我正在使用以下XSLT

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

 <xs:WhiteList>
  <item-name>TShirt</item-name>
  <item-name>Ball</item-name>
  <item-name>Green</item-name>
 </xs:WhiteList>
 <xsl:variable name="whiteList" select="document('')/*/xs:WhiteList" />

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

 <xsl:template match="*[(descendant-or-self::*[name()=$whiteList/item-name])"/>
</xsl:stylesheet>

但这不起作用。你能帮忙吗?

谢谢Nathan

共有3个答案

牧业
2023-03-14

没有什么可以阻止您在模板匹配表达式中使用document()函数。

以下生成所述输出:

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

  <xs:WhiteList>
    <item-name>TShirt</item-name>
    <item-name>Ball</item-name>
    <item-name>Bat</item-name>
  </xs:WhiteList>

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

  <xsl:template match="item[not(@item-name = document('')/*/xs:WhiteList/item-name)]"/>
</xsl:stylesheet>

作为附带说明,我建议不要滥用命名空间。您的xs: WhiteListhttp://www.w3.org/2001/XMLSchema命名空间无关。如果需要,您可以使用虚构的命名空间,例如xmlns: ut="my-实用程序节点",它不太可能与实际使用的任何内容冲突。

庄浩言
2023-03-14

在XSLT 1.0中,不能在xsl:template匹配模式中使用变量引用。您可能应该匹配项目,然后在模板内进行测试。

我还建议为白名单使用一个唯一的名称空间,而不是使用xs“http://www.w3.org/2001/XMLSchema“。

我注意到的另一件事是您的白名单中有Green而不是Bat

下面是一个更新了这三件事的示例。。。

XML输入

<catalog catalog-id="Primary">
    <product product-id="clothes">
        <items>
            <item item-name="TShirt">Brown</item>
            <item item-name="Pants">Green</item>
            <item item-name="Shirt">White</item>
        </items>
    </product>
    <product product-id="toys">
        <items>
            <item item-name="Ball">Cyan</item>
            <item item-name="Bat">Green</item>
            <item item-name="Racket">Blue</item>
        </items>
    </product>
</catalog>

XSLT 1.0

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

  <local:WhiteList>
    <item-name>TShirt</item-name>
    <item-name>Ball</item-name>
    <item-name>Bat</item-name>
  </local:WhiteList>
  <xsl:variable name="whiteList" 
    select="document('')/*/local:WhiteList/item-name"/>

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

  <xsl:template match="item">
    <xsl:if test="@item-name=$whiteList">
      <xsl:copy-of select="."/>
    </xsl:if>    
  </xsl:template>
</xsl:stylesheet>

XML输出

<catalog catalog-id="Primary">
   <product product-id="clothes">
      <items>
         <item item-name="TShirt">Brown</item>
      </items>
   </product>
   <product product-id="toys">
      <items>
         <item item-name="Ball">Cyan</item>
         <item item-name="Bat">Green</item>
      </items>
   </product>
</catalog>
龚玄天
2023-03-14
<?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:strip-space elements="*"/>
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template
        match="item[not(@item-name = 'TShirt' or @item-name = 'Ball' or @item-name = 'Bat')]"/>
</xsl:stylesheet>

这也会生成输出。这是基于xslt 1.0的。

 类似资料:
  • 问题内容: 在XML文档中,我具有共享相同名称的元素,但是属性的值定义了它是什么类型的数据,并且我想从文档中选择所有具有特定值的元素。我是否需要使用XPath(如果可以,您是否可以建议正确的语法)还是有更优雅的解决方案? 这是一些示例XML: 我想选择类型为的所有子代标签的内容。 PS-我正在尝试使用PHP与Netflix API进行接口-这对我的问题无关紧要,但是如果您想提出一种更好的方法,我非

  • 本文向大家介绍jquery 属性选择器(匹配具有指定属性的元素),包括了jquery 属性选择器(匹配具有指定属性的元素)的使用技巧和注意事项,需要的朋友参考一下 jQuery 选择器 在前面的章节中,我们展示了一些有关如何选取 HTML 元素的实例。 关键点是学习 jQuery 选择器是如何准确地选取您希望应用效果的元素。 jQuery 元素选择器和属性选择器允许您通过标签名、属性名或内容对 H

  • 我正在尝试使用Javascript选择此复选框 下面的代码可以工作,但并不理想 我试过这些 但它们并不起作用。有什么想法能让这件事成功吗? 数据值未硬编码的更新代码

  • 问题内容: 我试图通过将所有参数元素为type_id =“ 4218”的所有“ ”元素从URL解析XML文件? XML文件: 这是我的Java代码: 这段代码给了我所有元素,我不想要,我想要属性type_id =“ 4218”的所有元素! 问题答案: XPath是您的正确选择: 并遍历

  • 问题内容: 可以说我们有以下代码: 您将如何选择第一个属性等于3的孩子?我在想,也许这可以做到: …但是没有用 问题答案: 该伪类仅着眼于第一子节点,因此,如果第一个孩子是不是,则选择一无所有。 没有类似的属性过滤器伪类。一种简单的解决方法是选择每个对象,然后排除第一个对象之后的内容 当然,这仅适用于样式。如果您要出于样式之外的目的挑选该元素(因为标记看起来是任意XML而不是HTML),则必须使用

  • 问题内容: 请考虑以下代码: 如何选择具有属性的所有标签? 谢谢 问题答案: 使用“具有属性”选择器: 或选择一个该属性具有特定值的属性: “属性值起始于”,“属性值包含”等还有其他选择器。