我有以下XML数据结构:
<root>
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<promotions>
<promotion>
<header>
<id>1</id>
<name>Name 1</name>
</header>
<positions>
<position>
<id>1</id>
<name>Some position name 1</name>
</position>
<position>
<id>2</id>
<name>Some position name 2</name>
</position>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>2</id>
<name>Name 2</name>
</header>
<positions>
<position>
<id>3</id>
<name>Some position name 3</name>
</position>
</positions>
</promotion>
</promotions>
</root>
用作我的模板的主要数据源,如下所示:
<xsl:template match="root">
...
我需要通过&#34; filter.xml&#34;来过滤上面的内容。文件,包含要过滤掉的促销ID,并且需要使用 IE7 。这样的事情可能吗?
对于初学者,我尝试在 xsl:apply-templates select 语句中找到添加过滤器的方法,以便仅ID = 2的促销将由模板处理但失败了 - 是否有可能写出Xpath,它会说:
&#34;从根节点给我一切,但促销只有Id = 2&#34; ?
感谢。
EDIT1:
对命名空间感到抱歉 - 首先它不应该存在。至于filter.xml - 它尚未明确定义 - 目前,我使用以下内容:
<usedUpPromotions>
<header>
<promotionId>
1
</promotionId>
</header>
<header>
<promotionId>
2
</promotionId>
</header>
<header>
<promotionId>
3
</promotionId>
</header>
</usedUpPromotions>
我想使用类似的东西:
<xsl:apply-templates select="root[hereIsMyWhereId != (document('Load externalXmlHere')/select/IdtoFilterOut)"/>
但我似乎找不到以这种方式过滤数据的方法......
EDIT2:
我会尝试使用代码作为示例进行解释 - 让我们暂时假设我们有以下内容:
XmlData initialXmlData;
&lt; - 这是我们过滤前的XML数据
XmlData filter;
- &lt;这包含filter.xml数据
Html GenerateHtmlFromTemplate(XmlData initialXmlData) - this is my Xslt template
{
...some precessing here
}
我想修改我的模板以实现以下目标:
Html GenerateHtmlFromTemplate(XmlData initialXmlData, XmlData filter)
{
XmlData filteredData = data.FilterBy(filter);
...same processing here as above, but use 'filteredData', instead of 'initialXmlData'
}
我希望它现在更清楚:) - 主要问题,看起来我想过滤的Id元素是在数组变量中,所以我不能简单地使用:
在我的主要模板中 - 我绕过了问题,稍后通过过滤for-each循环,但我仍然想知道是否可以简单地告诉模板&#34;从现在开始使用过滤数据,而不是原创&#34;。
EDIT3:
@ michael.hor257k - 为了回答你的问题,我修改了你提供的模板:
Template.xml中:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="#"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ksx="http://www.test.com/test" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<xsl:output encoding="utf-8" indent="no" method="html"/>
<root xmlns="http://www.test.com/test">
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<promotions>
<promotion>
<header>
<id atr="tre">1</id>
<name>Promotion 1</name>
</header>
<positions>
<position>
<id>1</id>
<name>Position 1a</name>
</position>
<position>
<id>2</id>
<name>Position 1b</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>2</id>
<name>Promotion 2</name>
</header>
<positions>
<position>
<id>3</id>
<name>Position 2a</name>
</position>
</positions>
</promotion>
</promotions>
</root>
<xsl:param name="new-path" select="'new.xml'"/>
<xsl:variable name="new-promotions" select="document($new-path)/newPromotions/promotion" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ksx:root">
<xsl:copy>
<xsl:apply-templates select="ksx:promotions/ksx:promotion[not(ksx:header/ksx:id=$new-promotions/header/id)]"/>
<xsl:apply-templates select="$new-promotions"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
new.xml:
<?xml version="1.0" encoding="utf-8"?>
<newPromotions>
<promotion>
<header>
<id>2</id>
<name>New Promotion 2</name>
</header>
<positions>
<position>
<id>4</id>
<name>New Position 2A</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>3</id>
<name>New Promotion 3</name>
</header>
<positions>
<position>
<id>5</id>
<name>New Position 3A</name>
</position>
</positions>
</promotion>
</newPromotions>
如果您保存这些内容,并在Chrome中打开template.xml,它可以很好地工作 - 但我想要的是过滤掉外部模板节点的数据:
<xsl:template match="ksx:root">
所以,我试过这个:
<xsl:template match="ksx:root[ksx:promotion/ksx:header/ksx:id=1]">
我希望从 root 获取所有数据,但促销过滤到Id = 1的那些 - 但是它提供了所有数据而且没有错误,现在我注意到了这一点:
<xsl:template match="ksx:root[ksx:promotions/ksx:promotion/ksx:header/ksx:id=$new-promotions/header/id]">
导致错误&#34;变量不能在此表达式中使用&#34; - 所以我想,我想要做的事情可能是从模板节点外面做的......?
对于这种困惑感到抱歉 - 我希望现在更清楚了。我只是想将模板节点视为一种方法并且&#34;传递&#34;将数据过滤到它,而不是过滤其中的数据。
Edit4:
在我的具体案例中,我有很多&#34; root&#34;促销数据集,以及包含在处理期间隐藏的促销ID的小型外部XML文件。所以在我的情况下,过滤意味着:&#34;从根元素中取出所有内容,但过滤促销只有那些不在外部文件中的ID才会被处理&#34;。如果我有:
<root xmlns="http://www.test.com/test">
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<someData1>Some data 1</someData1>
<someData2>Some data 2</someData2>
<someData3>Some data 3</someData3>
<promotions>
<promotion>
<header>
<id>1</id>
<name>Promotion 1</name>
</header>
<positions>
<position>
<id>1</id>
<name>Position 1a</name>
</position>
<position>
<id>2</id>
<name>Position 1b</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>2</id>
<name>Promotion 2</name>
</header>
<positions>
<position>
<id>3</id>
<name>Position 2a</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>3</id>
<name>Promotion 3</name>
</header>
<positions>
<position>
<id>4</id>
<name>Position 3a</name>
</position>
</positions>
</promotion>
</promotions>
</root>
并过滤:
<?xml version="1.0" encoding="UTF-8"?>
<usedUpPromotions>
<id>1</id>
<id>2</id>
</usedUpPromotions>
然后我希望得到:
<root xmlns="http://www.test.com/test">
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<someData1>Some data 1</someData1>
<someData2>Some data 2</someData2>
<someData3>Some data 3</someData3>
<promotions>
<promotion>
<header>
<id>3</id>
<name>Promotion 3</name>
</header>
<positions>
<position>
<id>4</id>
<name>Position 3a</name>
</position>
</positions>
</promotion>
</promotions>
</root>
答案 0 :(得分:1)
要仅处理Id = 2的促销,您可以使用(来自root
的上下文):
<xsl:apply-templates select="promotions/promotion[header/id='2']"/>
以下是一个展示如何合并&#34;您的输入XML与重写的XML文档。给出:
<强> XML 强>
<root>
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<promotions>
<promotion>
<header>
<id>1</id>
<name>Promotion 1</name>
</header>
<positions>
<position>
<id>1</id>
<name>Position 1a</name>
</position>
<position>
<id>2</id>
<name>Position 1b</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>2</id>
<name>Promotion 2</name>
</header>
<positions>
<position>
<id>3</id>
<name>Position 2a</name>
</position>
</positions>
</promotion>
</promotions>
</root>
<强> new.xml 强>
<newPromotions>
<promotion>
<header>
<id>2</id>
<name>New Promotion 2</name>
</header>
<positions>
<position>
<id>4</id>
<name>New Position 2A</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>3</id>
<name>New Promotion 3</name>
</header>
<positions>
<position>
<id>5</id>
<name>New Position 3A</name>
</position>
</positions>
</promotion>
</newPromotions>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="new-path" select="'path/to/new.xml'"/>
<xsl:variable name="new-promotions" select="document($new-path)/newPromotions/promotion" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="promotions">
<xsl:copy>
<xsl:apply-templates select="promotion[not(header/id=$new-promotions/header/id)]"/>
<xsl:apply-templates select="$new-promotions"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>结果强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<promotions>
<promotion>
<header>
<id>1</id>
<name>Promotion 1</name>
</header>
<positions>
<position>
<id>1</id>
<name>Position 1a</name>
</position>
<position>
<id>2</id>
<name>Position 1b</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>2</id>
<name>New Promotion 2</name>
</header>
<positions>
<position>
<id>4</id>
<name>New Position 2A</name>
</position>
</positions>
</promotion>
<promotion>
<header>
<id>3</id>
<name>New Promotion 3</name>
</header>
<positions>
<position>
<id>5</id>
<name>New Position 3A</name>
</position>
</positions>
</promotion>
</promotions>
</root>
所以在我的情况下,过滤意味着:&#34;从根获取所有内容 元素,但筛选促销,所以只有那些ID不在 外部文件,将被处理&#34;。
我上面的回答有两件事:
如果您只想做#1但不想做#2,那么请更改:
<xsl:template match="promotions">
<xsl:copy>
<xsl:apply-templates select="promotion[not(header/id=$new-promotions/header/id)]"/>
<xsl:apply-templates select="$new-promotions"/>
</xsl:copy>
</xsl:template>
为:
<xsl:template match="promotions">
<xsl:copy>
<xsl:apply-templates select="promotion[not(header/id=$new-promotions/header/id)]"/>
</xsl:copy>
</xsl:template>
在给定的示例中,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<info>
<creationDate>2015-03-11 11:45:49</creationDate>
</info>
<promotions>
<promotion>
<header>
<id>1</id>
<name>Promotion 1</name>
</header>
<positions>
<position>
<id>1</id>
<name>Position 1a</name>
</position>
<position>
<id>2</id>
<name>Position 1b</name>
</position>
</positions>
</promotion>
</promotions>
</root>