1

例如,如果您以 XML 格式存储属性文件

<Properties>
    <Property value="abc">ABC1</Property>
    <Property value="...">...</Property>
</Properties>

然后我们可以使用 xslt 处理两个(属性,输入)XML 文件,并将 abc 元素(输入 xml 文件)替换为 ABC1(自定义输出 xml 文件),等等。

例如考虑我下面的输入 xml 文件

<?xml version="1.0" encoding="UTF-8"?>
       <Content>
          <abc>xxx
                 <def>zzz
                    <ghi>ccc</ghi>ttt
                     <dynamic val="hello" xmlns="http://abc.com" />
                      world
                     <dynamic val="hi" xmlns="http://abc.com" />
                       <dynAttr>
                         <dyn value=123 />
                         <dyn value=222 />
                       </dynAttr>
                         <lmn>data</lmn>

                   </def>
                </abc>
         </Content>

属性文件由为输入 xml 文件的每个标记定义的属性组成,如果没有为该输入 xml 文件标记定义属性,则转换后的 xml 标记与输入 xml 文件标记具有相同的标记名称。

<?xml version="1.0" encoding="UTF-8"?>
<Properties>
             <Property value="Content">CONTENT12</Property>
             <Property value="abc">ABC1</Property>
             <Property value="def">www</Property>
              <Property value="ghi">yyy</Property>
             <Property value="dynamic">Dynamic1</Property>
             <Property value="dynAttr">DynAttribute</Property>
</Properties>

使用 xslt 并编写一个 xsl 文件,该文件引用属性 xml 文件,当应用于给定的输入 xml 文件并生成转换后的 xml 文件时,如图所示

<?xml version="1.0" encoding="UTF-8"?>

                <www>zzz
                    <yyy>ccc</yyy>ttt
                     <Dynamic1 val="hello" xmlns="http://abc.com>hello</Dynamic1>
                      world
                     <Dynamic1 val="hi" xmlns="http://abc.com>hi</Dynamic1>
                       <DynAttribute>
                         <dyn>123</dyn>
                         <dyn>222</dyn>
                       </DynAttribute>
                         <lmn>data</lmn>
                   </www>
if the above code is my requirement then what must be the relative xpath expression in your answer <xsl:template match=" ">
4

1 回答 1

2

您的示例文件格式不正确,但如果您修复它,并且您的属性文件是 prop.xml,这应该可以工作:

<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:template match="*">
 <xsl:variable name="n" select="name()"/>
 <xsl:variable name="new">
  <xsl:for-each select="document('prop.xml')">
   <xsl:choose>
    <xsl:when test="key('n',$n)">
     <xsl:value-of select="key('n',$n)"/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:value-of select="$n"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:for-each>
 </xsl:variable>
 <xsl:element name="{$new}">
  <xsl:copy-of select="@*"/>
  <xsl:apply-templates/>
 </xsl:element>
</xsl:template>

<xsl:key name="n" match="Property" use="@value"/>

</xsl:stylesheet>

您的问题没有说明重命名的元素应该在哪个命名空间中。上面的代码总是将它们放在无命名空间中。如果您希望它们与原始名称位于同一名称空间中,请将 xsl:element 行更改为

 <xsl:element name="{$new}" namespace="{namespace-uri()}">

最灵活的替代方法可能是在属性文件中同时指定本地名称和命名空间 uri。

更新

如果如评论和更新的答案中所述,您希望保留命名空间并仅处理def元素,则进行如下小的修改:

<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:template match="/">
 <xsl:apply-templates select="//def"/>
</xsl:template>

<xsl:template match="*">
 <xsl:variable name="n" select="name()"/>
 <xsl:variable name="new">
  <xsl:for-each select="document('prop.xml')">
   <xsl:choose>
    <xsl:when test="key('n',$n)">
     <xsl:value-of select="key('n',$n)"/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:value-of select="$n"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:for-each>
 </xsl:variable>
 <xsl:element name="{$new}" namespace="{namespace-uri()}">
  <xsl:copy-of select="@*"/>
  <xsl:apply-templates/>
 </xsl:element>
</xsl:template>

<xsl:key name="n" match="Property" use="@value"/>

</xsl:stylesheet>
于 2012-04-08T13:20:57.047 回答