XSLT - 包含/排除多个标记

时间:2017-01-02 07:14:20

标签: xml xslt

我需要制作XML处理例程,该例程会从提供给例程的XML文档中删除某些XML标记。 XML文档不是固定的,但已知它没有使用任何名称空间。

该例程将有两个XML标记名列表:

  • 转换后应包含的标签
  • 转换后应排除的标签

排除更具优势,即如果两个列表中的标记相同,则不应选择该标记。如果排除了父标记,则也应排除子标记。

我已经在网络上看到了很好的示例和答案,但在单个XSLT中找不到完全可行的解决方案来解决我的问题。

这个解决方案似乎非常明确和合理,但是有可能拥有" BlackList"也在同一个XSLT中?: XSLT - How to keep only wanted elements from XML

编辑:排除和包含列表彼此独立。即排除列表不包含所有不在包含列表中的标记,反之亦然。

EDIT2:需要简化的流程:XML - >删除排除标记 - >删除除包含标记以外的内容。

EDIT3:固定链接。

EDIT4:包含所有用例的维恩图(总是需要一个部分):

Venn diagram

1 个答案:

答案 0 :(得分:1)

---由于澄清而修改了答案---

以下样式表:

XSLT 1.0

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

<my:whitelist>
    <item>America</item>
    <item>USA</item>
    <item>California</item>
    <item>LosAngeles</item>
    <item>SanFranciso</item>
    <item>Mexico</item>
    <item>Tijuana</item>
</my:whitelist>

<my:blacklist>
    <item>Mexico</item>
</my:blacklist>

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

<xsl:template match="*[not(name()=document('')/*/my:whitelist/item) or name()=document('')/*/my:blacklist/item]"/>

</xsl:stylesheet>

应用于以下输入:

<强> XML

<America>
   <USA>
      <NewYork>
         <NewYork>no</NewYork>
         <Albany>yes</Albany>
      </NewYork>
      <California>
         <LosAngeles>no</LosAngeles>
         <SanFranciso>no</SanFranciso>
      </California>
   </USA>
   <Canada>
      <Vancouver>no</Vancouver>
      <Montreal>yes</Montreal>
   </Canada>
   <Mexico>
      <Tijuana>no</Tijuana>
   </Mexico>
</America>

将返回:

<?xml version="1.0" encoding="UTF-8"?>
<America>
   <USA>
      <California>
         <LosAngeles>no</LosAngeles>
         <SanFranciso>no</SanFranciso>
      </California>
   </USA>
</America>

当然,这只有在允许两个列表重叠时才有意义 - 即当黑名单覆盖白名单时。

加了:

如果您的处理器无法解析返回样式表本身的document()函数,请尝试以下替代方法:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:variable name="whitelist">
    <item>America</item>
    <item>USA</item>
    <item>California</item>
    <item>LosAngeles</item>
    <item>SanFranciso</item>
    <item>Mexico</item>
    <item>Tijuana</item>
</xsl:variable>

<xsl:variable name="blacklist">
    <item>Mexico</item>
</xsl:variable>

<xsl:template match="*">
    <xsl:if test="name()=exsl:node-set($whitelist)/item and not (name()=exsl:node-set($blacklist)/item)">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

演示:http://xsltransform.net/3NSSEvk

相关问题