使用xsl从外部文档替换

时间:2013-09-26 18:39:59

标签: xml xslt replace xslt-1.0 xslt-2.0

我尝试使用properties.xml中的值替换源文件中的变量@mybook.01@,该值与源文件中的book-name元素匹配,并且properties.xml中为group id

这是我的源文件:

<books>
   <us-country-factory>
      <book-name>books/props/Classic</book-name>
      <store-property name="book1" type="java.lang.String">@mybook.01@</store-property>
      <store-property name="book2" type="java.lang.String">@mybook.01@</store-property>
      <store-property name="book2">CLIENT</store-property>
   </us-country-factory>
   <us-country-factory>
      <book-name>books/props/Classic1</book-name>
      <store-property name="book1" type="java.lang.String">@mybook.01@</store-property>
      <store-property name="book2" type="java.lang.String">@mybook.01@</store-property>
   </us-country-factory>   
</books>

这是我的properties.xml文件:

<variables>
    <group id="books/props/Classic">
        <variable id="book1">
            <mybook.01>123</mybook.01>
        </variable>
        <variable id="book2">
            <mybook.01>789</mybook.01>
        </variable>
    </group>
    <group id="books/props/Classic1">
        <variable id="book1">
            <mybook.01>ab2</mybook.01>
        </variable>
        <variable id="book2">
            <mybook.01>rt67</mybook.01>
        </variable> 
    </group>    
</variables>

因此,预期输出将如下所示:

<books>
   <us-country-factory>
      <book-name>books/props/Classic</book-name>
      <store-property name="book1" type="java.lang.String">123</store-property>
      <store-property name="book2" type="java.lang.String">789</store-property>
   </us-country-factory>
   <us-country-factory>
      <book-name>books/props/Classic1</book-name>
      <store-property name="book1" type="java.lang.String">ab2</store-property>
      <store-property name="book2" type="java.lang.String">rt67</store-property>
   </us-country-factory>   
</books>
    source.xml中的
  1. book-nam e与properties.xml
  2. 中的group id匹配 source.xml中的
  3. store-property名称与properties.xml
  4. 中的variable id匹配 source.xml中的
  5. @mybook.01@将替换为properties.xml
  6. 中的<mybook.01>

    当properties.xml和一个智能节点中只有组时,我能够得到这个,但不知道如何使用匹配的模板循环组。

    这是我的xsl文件:

    <?xml version="1.0" encoding="US-ASCII"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    version="2.0">
        <xsl:strip-space elements="*"/>
        <xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes"/>
    
        <xsl:key name="props" match="variable/*"
                 use="concat(../@id,'&#xd;',name(.))"/>  
        <xsl:template match="book-name">
            <xsl:apply-templates select="store-property"/>
        </xsl:template>               
        <xsl:template match="store-property">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:variable name="id" select="@name"/>
                <xsl:analyze-string select="." regex="@(.*?)@">
                    <xsl:matching-substring>
                        <xsl:value-of select="key('props',concat($id,'&#xd;',regex-group(1)),
                                doc('properties.xml'))"/>
                    </xsl:matching-substring>
                    <xsl:non-matching-substring>
                        <xsl:value-of select="."/>
                    </xsl:non-matching-substring>
                </xsl:analyze-string>
            </xsl:copy>
        </xsl:template> 
        <xsl:template match="@*|node()">
            <!--identity for all other nodes-->
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    

1 个答案:

答案 0 :(得分:1)

你可以这样做......

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="props" select="document('properties.xml')"/>

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

    <xsl:template match="store-property[matches(.,'^@')]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:value-of select="$props/*/group[@id=current()/../book-name]/variable[@id=current()/@name]/*[local-name()=tokenize(current(),'@')[2]]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

XML输出(使用提供的XML示例)

<books>
   <us-country-factory>
      <book-name>books/props/Classic</book-name>
      <store-property name="book1" type="java.lang.String">123</store-property>
      <store-property name="book2" type="java.lang.String">789</store-property>
      <store-property name="book2">CLIENT</store-property>
   </us-country-factory>
   <us-country-factory>
      <book-name>books/props/Classic1</book-name>
      <store-property name="book1" type="java.lang.String">ab2</store-property>
      <store-property name="book2" type="java.lang.String">rt67</store-property>
   </us-country-factory>
</books>