2012-07-22 48 views
-1

我有一个XML我想将其转换为xslt。 输入如下所示。XSL - 删除包含特定条件的父节点

<xmeml> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>tuvw</Unit3> 
    </Test> 
    <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>uvwx</Unit3> 
    </Test> 
    <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
</xmeml> 

输出应该看起来像这样。

<xmeml> 
<Doc> 
    <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
</xmeml> 

我想删除任何符合以下条件的测试节点。 - Unit3子节点以tuv或uvw开头。 - AND单元和单元2的值都发现在另一个测试节点中重复/复制

在此先感谢您的帮助。

+0

user1540142,我更新了我的答案。这是你想要的吗? – 2012-07-22 06:47:10

+0

嗨,你在这里看起来很新鲜,所以我想我会解释为什么这是被低估的:向我们表明,在向我们寻求帮助之前,你已经有了一个好主意。例如:你有什么尝试过自己?它对你有什么问题?如果您可以将此添加到您的问题中,我们将不仅能够更好地指出您的错误,我们会更好地帮助您:) – 2012-07-24 08:30:32

+0

谢谢Taryn,将来会做。这是一个巨大的信息和人员资源。我很快就学会了行话和正确的协议。 – user1540142 2012-07-24 12:15:14

回答

1

这个怎么样的调整Dimitre的解决方案......

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kTest" match="Test" use="concat(Unit, '+', Unit2)"/> 

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

<xsl:template match= 
    "Test[key('kTest', concat(Unit, '+', Unit2))[2]] 
    [starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]"/> 
</xsl:stylesheet> 

据我了解,改造的规则是:

  1. 将所有节点作为是,除特别说明外以下。
  2. 排除所有测试节点具有以下属性:

2.1存在另一个测试节点(称之为测试(其他))的文件,使得:

(Test(reference)/Unit = Test(other)/Unit) AND 
    (Test(reference)/Unit2 = Test(other)/Unit2) 

2.2 UNIT3孩子的参考测试节点以tuv或uvw开头

此输出与OP发布的完全相同。有趣的是,如果我已经正确地理解了这个问题,Dimitre最近刚刚提供了一个解决方案,几乎和你在这里的问题一样,这就是XSL comparison of nodes。再说一遍,如果我已经正确地理解了你的问题,这个标题就会让人产生误解。 “删除重复”通常意味着去重复,如(1,2,2,3) - >(1,2,3);而像(1,2,2,3) - >(1,3)这样的要求通常被描述为“选择唯一节点/值”。

+0

是的,它是一个棘手的描述。基本上我想删除所有测试节点,其中单元3的值以tuv或uvw开头。作为一个检查,但我还需要看看是否有任何重复条目由Unit和Unit2值定义。所以我认为真正的问题是,如果Unit3以tuv或uvw开头,并且它的Unit和Unit2值在另一个Test节点中重复,则将其删除。那有意义吗。 – user1540142 2012-07-22 11:54:08

+0

看来你的工作是完美的。谢谢你亲爱的澳大利亚;)谢谢你,Dimite因为成为病人。 – user1540142 2012-07-22 12:05:28

+0

@ user1540142:问题仍然没有编辑,相当混乱。我重申,您必须编辑问题并明确表达清楚。对于将来的问题,请特别注意提出明确而明确的问题,以免浪费读者和您自己的时间。每当有人提出含糊不清的问题时,他们只是在描述他们提出的问题 - 而不是他们认为的问题。 – 2012-07-22 15:07:08

1

该转化(Muenchian分组的 - 基于):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kTest" 
    match="Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]" 
      use="concat(Unit, '+', Unit2)"/> 

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

<xsl:template match= 
    "Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')] 
    [not(generate-id() 
    = 
    generate-id(key('kTest', concat(Unit, '+', Unit2))[last()]))]"/> 
</xsl:stylesheet> 

当所提供的XML文档施加:

<xmeml> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>1234</Unit2> 
      <Unit3>tuvw</Unit3> 
     </Test> 
     <Test> 
      <Unit>bcd</Unit> 
      <Unit2>2345</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>3456</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
      <Unit>cde</Unit> 
      <Unit2>3456</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>1234</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
      <Unit>def</Unit> 
      <Unit2>4567</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>1234</Unit2> 
      <Unit3>uvwx</Unit3> 
     </Test> 
     <Test> 
      <Unit>efg</Unit> 
      <Unit2>2345</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
</xmeml> 

产生正确的结果(实现所有要求) :

<xmeml> 
    <Doc> 
     <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>uvwx</Unit3> 
     </Test> 
     <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
</xmeml> 

更新

的OP有自己的问题,这是不明确的,并没有精确定义的解释。

有了相当大的猜测,这里是他可能想...:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kTest" 
    match="Test" use="concat(Unit, '+', Unit2)"/> 

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

<xsl:template match= 
    "Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')] 
    [not(generate-id() 
    = 
    generate-id(key('kTest', concat(Unit, '+', Unit2)) 
            [not(position()=1)]) 
       )]"/> 
</xsl:stylesheet> 

当这种转变是在所提供的XML文档(以上)应用,现在的结果与OP认为什么相同是想要的结果

<xmeml> 
    <Doc> 
     <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
</xmeml> 
+0

谢谢Dimitre,:)作品一种享受! – user1540142 2012-07-22 03:30:02

+0

嗨Dimitre,实际上它看起来像没有从底部拾取后者的候选人,第二个测试节点。匹配单元和Unit2值和Unit3以uvw开头。 – user1540142 2012-07-22 04:08:00

+0

@ user1540142:我不明白你在说什么。你能解释一下吗?转型严格执行所有要求。 – 2012-07-22 04:10:57