从文件中使用XPATH并添加相关属性

时间:2013-12-20 04:37:17

标签: xslt dynamic xpath attributes

可能是我的XSL方法错了?请纠正我处理这种情况的方法

我想从映射文件中获取XPATH和Attrs,然后使用XPATH进行匹配,并将属性应用于XML。

这是我的3个输入文件:

mappings.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
    <map xpath="//title" class="title" others="moreToCome" />
    <map xpath="//subtitle" class="subtitle" others="moreToCome" />
    <map xpath="//p" class="p" others="moreToCome" />
</mappings>

Source.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <title>title text</title>
    <subtitle>subtitle text</subtitle>
    <p>subtitle text</p>
</root>

StyleMapping.xsl

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="fMappings" select="document('mappings.xml')" />
<xsl:variable name="xpath"><xsl:text>justToMakeItGlobal</xsl:text></xsl:variable>

<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*" />
  </xsl:copy>
  <!-- loop thru map in mappings.xml -->
  <xsl:for-each select="$fMappings//mappings/map">
    <xsl:call-template name="dyn">
      <xsl:with-param name="xpath" select="@xpath" />
      <xsl:with-param name="class" select="@class" />
      <xsl:with-param name="others" select="@others" />
    </xsl:call-template>
  </xsl:for-each>
</xsl:template>

<xsl:template match="$xpath" mode="dyn">
  <xsl:param name="xpath"/>
  <xsl:param name="class"/>
  <xsl:param name="others"/>
  <xsl:attribute name="class"><xsl:value-of select="$class" /></xsl:attribute>
  <xsl:attribute name="others"><xsl:value-of select="$others" /></xsl:attribute>
</xsl:template>

</xsl:stylesheet>

这是计划要做的,但我没有在XSLT中找到正确的方法:
1.阅读mappings.xml文件
2.循环遍历每个地图标签
3.抓住xpath和attr的
4.将模板匹配/选择应用于上面的xpath
5.将attr添加到上面选定的节点

的Output.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <title class="title" others="moreToCome">title text</title>
    <subtitle class="subtitle" others="moreToCome">subtitle text</subtitle>
    <p class="p" others="moreToCome">subtitle text</p>
</root>

1 个答案:

答案 0 :(得分:0)

我认为您不能拥有带有计算匹配模式的模板。让我提出一个不同的方法:

<强> mappings.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
    <map elem="title" class="Title" others="moreToCome1" />
    <map elem="subtitle" class="Subtitle" others="moreToCome2" />
    <map elem="p" class="P" others="moreToCome3" />
</mappings>

<强>样式表

<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="mappings" select="document('mappings.xml')/mappings" />

<xsl:template match="*">
<xsl:variable name="elem" select="name()" />
<xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:if test="$elem = $mappings/map/@elem">
        <xsl:attribute name="class">
            <xsl:value-of select="$mappings/map[@elem=$elem]/@class"/>
        </xsl:attribute>
        <xsl:attribute name="others">
            <xsl:value-of select="$mappings/map[@elem=$elem]/@others"/>
        </xsl:attribute>    
    </xsl:if>
    <xsl:apply-templates/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

使用以下源XML进行测试:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <title original="yes">title text</title>
    <subtitle>subtitle text</subtitle>
    <p>para text</p>
    <nomatch attr="test">another text</nomatch>
</root>

结果:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <title original="yes" class="Title" others="moreToCome1">title text</title>
    <subtitle class="Subtitle" others="moreToCome2">subtitle text</subtitle>
    <p class="P" others="moreToCome3">para text</p>
    <nomatch attr="test">another text</nomatch>
</root>