XSL匹配一些但不是全部

时间:2011-03-17 16:07:37

标签: xml xslt

an earlier post提供了Dimitre Novatchev提供的解决方案。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
  <xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>
  <xsl:key name="kPhysByName" match="KB_XMod_Modules" use="Physician"/>
  <xsl:template match="/">
    <result>
      <xsl:apply-templates/>
    </result>
  </xsl:template>
  <xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
    <xsl:variable name="vCur" select="."/>
    <xsl:for-each select="document('doc2.xml')">
      <xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
      <xsl:copy>
        <items>
          <item>
            <label>
              <xsl:value-of select="$vMod/Physician"/>
            </label>
            <value>
              <xsl:value-of select="$vMod/XModID"/>
            </value>
          </item>
        </items>
      </xsl:copy>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

我现在需要在我的源XML中使用其他字段,并且需要现有标签完好无损但我遇到了问题。

<instance>
  <NewTag>Hello</newTag1>
  <AnotherNewTag>Everyone</AnotherNewTag>
  <InfBy1>Dr Phibes</InfBy1>
  <InfBy2>Dr X</InfBy2>
  <InfBy3>Dr Chivago</InfBy3>
</instance>

删除其他标签和输出

<result xmlns:my="my:my">
  HelloEveryone 
  <items>
    <item>
      <label>Dr Phibes</label>
      <value>60</value>
    </item>
  </items>
  ...

我一直在尝试

<xsl:otherwise>
  <xsl:copy-of select=".">
  </xsl:copy-of>
</xsl:otherwise>

但作为一个xsl新手我似乎无法让这个工作。我有一种感觉,我正在咆哮错误的树!

有没有人有任何想法?

谢谢,

威尔

2 个答案:

答案 0 :(得分:2)

您的NewTagAnotherNewTag元素与Built-in Template Rules匹配。如果你想要另一种转换,你需要声明这样的规则。

  

需要现有标签完整

然后您正在寻找identity rule

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

答案 1 :(得分:0)

这是<xsl:apply-templates>的副作用,它试图为遇到的每个子节点找到匹配的模板,并结合隐含的XSLT“默认行为”。

在您的情况下,它会遇到<NewTag><AnotherNewTag>,但这些节点没有模板。

捕获此案例的默认行为(隐藏的默认模板)会将元素的文本值复制到输出流。

<NewTag>的文本值为“Hello”,<AnotherNewTag>的文本值为“Everyone”,因此您会看到“HelloEveryone”。

如果您不想这样做,请编写一个捕获这些节点的模板:

<xsl:template match="NewTag|AnotherNewTag">
  <xsl:copy-of select="." />
</xsl:template>

或者,编写一个捕获任何未处理元素节点的文件:

<!-- empty templates do nothing (matched nodes do not appear in the output) -->
<xsl:template match="*" />

如果您想要复制未处理的节点但仍希望以递归方式在其中应用模板,则可以使用身份模板(@ Alejandro的答案显示)。