【问题标题】:xsl file using properties.xml file in order to transform an xml file into the xml file with custom tags defined in properties.xml file使用 properties.xml 文件的 xsl 文件,以便将 xml 文件转换为带有 properties.xml 文件中定义的自定义标签的 xml 文件
【发布时间】:2012-04-10 16:24:27
【问题描述】:

如果您以 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=" ">

【问题讨论】:

  • @Maestro13:您好,您对上述问题有什么解决方案

标签: xml xslt properties


【解决方案1】:

您的示例文件格式不正确,但如果您修复它,并且您的属性文件是 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。

更新

如果如 cmets 和更新的答案中所述,您希望保留命名空间并仅处理 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>

【讨论】:

  • 感谢您的回复。但是当我们使用 copy-of 或任何复制标签时,我还将获得与输入 xml 文件相关联的另一个命名空间,而不是必需的命名空间,您能建议任何替代方案吗?
  • 我上面唯一使用 copy-of 的地方是复制属性。您没有给出任何需要更改属性名称的指示,或者就此而言,如果您的源文件中有名称空间,您希望如何将元素名称与您的属性文件匹配(使用名称空间 URI 并忽略前缀,或者如上所述忽略命名空间 uri 并匹配包括前缀在内的名称)如果你编辑你的问题,给出命名空间使用的指示,如果它仍然不合适,我会修改我的答案。
  • @David Carlisle:谢谢,代码运行良好,但我可以知道
  • @David Carlisle:如果我想从输入 xml 文档的特定节点匹配并尝试使用根节点作为匹配节点构建我的输出 xml,应该是什么相对 xpath 表达式如果我希望 作为根节点,不包括其父节点 CONTENT12 和 ABC1 从输出中。我猜它可能像
  • @David Carlisle:请参考编辑后的问题,你能回答我吗。我非常渴望知道答案。
猜你喜欢
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2017-01-05
  • 1970-01-01
相关资源
最近更新 更多