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

时间:2017-03-16 01:44:02

标签: xml xslt

您好我有以下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>

标准是仅复制&#34; item-name&#34;属性值是TShirt,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>

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

由于 森

3 个答案:

答案 0 :(得分:1)

    C:\Users\zafaque>echo %M2_HOME%
E:\softwares\apache-maven-3.3.9

C:\Users\zafaque>mvn --version
Error: Could not find or load main class org.codehaus.plexus.classworlds.launcher.Launcher

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

答案 1 :(得分:0)

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

我还建议您为白名单使用唯一的命名空间,而不是使用xmlns: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>

答案 2 :(得分:0)

没有什么可以阻止您在模板匹配表达式中使用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-utility-nodes"这样的虚构命名空间,它不太可能与实际使用的任何内容冲突。