Xml 如何在模板中迭代xsl中的变量?

Xml 如何在模板中迭代xsl中的变量?,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我想设置一个变量,其中包含要从文档中排除的节点。我的理由是,我希望非编码人员能够简单地从xml文档中删除内容 我的XML如下所示: <?xml version="1.0" encoding="ISO-8859-1"?> <document> <content name="location">New York</content> <content name="thing">Car</content> <

我想设置一个变量,其中包含要从文档中排除的节点。我的理由是,我希望非编码人员能够简单地从xml文档中删除内容

我的XML如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>
<document>
   <content name="location">New York</content>
   <content name="thing">Car</content>
   <content name="location">Baltimore</content>
</document>
<document>
       <content name="thing">Car</content>
 </document>

纽约
汽车
巴尔的摩
我的XSL:

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

<xsl:variable name='exclude'>
    <content name="location">New York</content>
    <content name="location">Baltimore</content>
</xsl:variable>

<xsl:template match="content">
<!--The problem is here. 
<xsl:for-each select="?iterate?">
  <xsl:if test="not(?If a match isn't found, copy?)">
  <xsl:copy-of select="." />
  </xsl:if>
</xsl:for-each>
-->
</xsl:template>

这里的问题不是如何迭代,而是变量是结果树片段,而不是节点集。要避免此问题,可以使用内部元素而不是变量:

XSLT1.0

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

<my:exclude>
    <content name="location">New York</content>
    <content name="location">Baltimore</content>
</my:exclude>

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

<!-- exclude listed nodes -->
<xsl:template match="content[document('')/xsl:stylesheet/my:exclude/content[. = current() and @name = current()/@name]]"/>

</xsl:stylesheet>
<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="exclude">
    <content name="location">New York</content>
    <content name="location">Baltimore</content>
</xsl:variable>

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

<xsl:template match="content">
    <xsl:if test="not(exsl:node-set($exclude)/content[. = current() and @name = current()/@name])">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

纽约
巴尔的摩

补充: 要在开始时使用变量,必须执行以下操作:

XSLT1.0

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

<my:exclude>
    <content name="location">New York</content>
    <content name="location">Baltimore</content>
</my:exclude>

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

<!-- exclude listed nodes -->
<xsl:template match="content[document('')/xsl:stylesheet/my:exclude/content[. = current() and @name = current()/@name]]"/>

</xsl:stylesheet>
<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="exclude">
    <content name="location">New York</content>
    <content name="location">Baltimore</content>
</xsl:variable>

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

<xsl:template match="content">
    <xsl:if test="not(exsl:node-set($exclude)/content[. = current() and @name = current()/@name])">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

纽约
巴尔的摩

您需要使用哪个XSLT 1.0处理器?该变量是一个结果树片段,因此需要首先将其转换为一个节点集,并且扩展函数的名称空间可以是特定于处理器的(例如,Microsoft Edge或IE或Microsoft的XslTransform需要与大多数其他处理器支持的EXSLT不同的URI)。它不是Microsoft。它实际上是内置在我正在使用的程序中…某个地方。我会记住这一点。谢谢。比较可能太简单了。比较:(a)节点值相同;(b) 属性
name
的值相同;根据OP问题的不同,我认为可能会有“任何/各种”节点被排除在xml之外,例如,
也将其删除
。简单就可以了。我完全控制着这份文件。这是有道理的,但当我测试它时,输出并不排除。行“”看起来模板在任何方面都不匹配。我正在使用这个测试站点:@JoshuaHedges我担心这个方法不会适用于大多数在线测试人员(如果有的话),因为他们无法将
文档(“”)
解析为当前样式表。是的,你可能是对的。代码似乎很可靠。我有没有办法使用一个变量而不是一个新的节点和名称空间?这听起来可能有点奇怪,但这段代码是一个庞大的xml搜索库(Watson Explorer)的一部分。我不确定它有什么不同,但我看到了我的文章中添加的内容。还请注意Martin Honnen对某些MS处理器的评论,
node-set()
函数需要不同的名称空间。