XML - XSLT - 使用两个 XML 文件 - 参考另一个 XML 文件的 XML 文件的添加 [英] XML - XSLT - Using two XML files - Additions to XML file consulting another XML file

查看:53
本文介绍了XML - XSLT - 使用两个 XML 文件 - 参考另一个 XML 文件的 XML 文件的添加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题,对我来说有点棘手,

I have the following problem that, for me, is kind of tricky,

基本上,我需要能够使用存储在另一个 XML 文件中的数据修改 XML 输入文件,因此我必须使用 2 个输入 XML 文件,

Basically I need to be able to modify a XML input file with data that I have stored in another XML file, so I would have to use 2 input XML files,

我有以下 XML 文件,这是我要修改的文件(基本上,只需对其进行添加):

I have the following XML file, which is the one I want to modify (basically, just make additions to it):

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
    <text-prop name="displayName">PersonTemplate</text-prop>
    <setup>
        <simple-master-page name="MasterPage" id="2">
            <footer>
                <text id="3">
                    <prop name="contentType">html</prop>
                    <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
                </text>
            </footer>
        </simple-master-page>
    </setup>
    <body>
        <table id="4">  
            <column id="17"/>
            <column id="18"/>
            <column id="19"/>
            <header>
                <row id="5">
                    <cell id="6">
                        <label id="20">
                            <text-prop name="text">NameTitle</text-prop>
                        </label>
                    </cell>
                    <cell id="7">
                        <label id="21">
                            <text-prop name="text">CityTitle</text-prop>
                        </label>
                    </cell>
                    <cell id="8">
                        <label id="22">
                            <text-prop name="text">AgeTitle</text-prop>
                        </label>
                    </cell>
                </row>
            </header>
            <detail>
                <row id="9">
                    <cell id="10"/>
                    <cell id="11"/>
                    <cell id="12"/>
                </row>
            </detail>
        </table>
    </body>
</report>

我想通过查阅另一个 XML 文件来修改/添加它,这个文件为我提供了我想放入第一个 XML 文件的数据:

And I want to make modify/make additions to it by consulting another XML file, this one, that gives me the data I want to put in the first XML file:

<?xml version="1.0" encoding="utf-8"?>
<model>
    <layouts>
        <layout ID="001" name="PersonTemplate" format="Table" nFields="3" >
            <fields>
                <field name="NameTitle"/>
                <field name="CityTitle"/>
                <field name="AgeTitle"/>
            </fields>
        </layout>
        <layout ID="002" name="SchoolTemplate" format="Table" nFields="3" >
            <fields>
                <field name="NameTitle"/>
                <field name="LocationTitle"/>
                <field name="MaxCapacityTitle"/>
            </fields>
        </layout>
    </layouts>
    <reports>
        <report layoutID="001">
            <params>
                <sources>
                    <source name="source1" dbURL="sampledb1.com" user="user1" password="dXNlcjE=" driver="dbDriver"/>
                    <source name="source2" dbURL="sampledb2.com" user="user2" password="dXNlcjI=" driver="dbDriver"/>
                </sources>
                <set name="set1" source="source1" querie="select Name, City, Age from PeopleTable" >
                    <qFields>
                        <qField name="Name" type="string"/>
                        <qField name="City" type="string"/>
                        <qField name="Age" type="integer"/>
                    </qFields>
                </set>
            </params>
        </report>
        <report layoutID="002">
            <params>
                <sources>
                    <source name="source1" dbURL="sampledb1.com" user="user1" password="dXNlcjE=" driver="dbDriver"/>
                </sources>
                <set name="Data Set" dataSource="source1" querie="select Name, Location, MaxCapacity from SchoolsTable" >
                    <qFields>
                        <qField name="Name" type="string"/>
                        <qField name="Location" type="string"/>
                        <qField name="MaxCapacity" type="integer"/>
                    </qFields>
                </set>
            </params>
        </report>
    </reports>
</model>

所以,我想生成以下 XML 文件:

So, I want to produce the following XML file:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
    <text-prop name="displayName">PersonTemplate</text-prop>
     <data-sources>
        <data-source extensionID="this.is.a.fixed.value" name="source1">
            <prop name="DriverClass">dbDriver</prop>
            <prop name="databaseURL">sampledb1.com</prop> 
            <prop name="dbUser">user1</prop>
            <encrypted-prop name="dbPassword" encryptionID="base64">dXNlcjE=</encrypted-prop>
        </data-source>
    </data-sources>
    <data-sets>
        <data-set extensionID="this.is.a.fixed.value" name="set1">
            <list-prop name="columnHints">
                <struct>
                    <prop name="columnName">Name</prop>
                    <text-prop name="displayName">Name</text-prop>
                    <text-prop name="heading">Name</text-prop>
                </struct>
                <struct>
                    <prop name="columnName">City</prop>
                    <text-prop name="displayName">City</text-prop>
                    <text-prop name="heading">City</text-prop>
                </struct>
                <struct>
                    <prop name="columnName">Age</prop>
                    <text-prop name="displayName">Age</text-prop>
                    <text-prop name="heading">Age</text-prop>
                </struct>
            </list-prop>
            <struct name="cachedMetaData">
                <list-prop name="resultSet">
                    <struct>
                        <prop name="position">1</prop>
                        <prop name="name">Name</prop>
                        <prop name="dataType">string</prop>
                    </struct>
                    <struct>
                        <prop name="position">2</prop>
                        <prop name="name">City</prop>
                        <prop name="dataType">string</prop>
                    </struct>
                    <struct>
                        <prop name="position">3</prop>
                        <prop name="name">Age</prop>
                        <prop name="dataType">integer</prop>
                    </struct>
                </list-prop>
            </struct>
            <prop name="dataSource">source1</prop>
            <list-prop name="resultSet">
                <struct>
                    <prop name="position">1</prop>
                    <prop name="name">Name</prop>
                    <prop name="dataType">string</prop>
                </struct>
                <struct>
                    <prop name="position">2</prop>
                    <prop name="name">City</prop>
                    <prop name="dataType">string</prop>
                </struct>
                <struct>
                    <prop name="position">3</prop>
                    <prop name="name">AGE</prop>
                    <prop name="dataType">integer</prop>
                </struct>
            </list-prop>
            <xml-prop name="queryText"><![CDATA[select Name, City, Age from PeopleTable]]></xml-prop>
        </data-set>
    </data-sets>
    <setup>
        <simple-master-page name="MasterPage" id="2">
            <footer>
                <text id="3">
                    <prop name="contentType">html</prop>
                    <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
                </text>
            </footer>
        </simple-master-page>
    </setup>
    <body>
        <table id="4">
            <prop name="dataSet">set1</prop>
            <list-prop name="boundDataColumns">
                <struct>
                    <prop name="name">Name</prop>
                    <text-prop name="displayName">Name</text-prop>
                    <expression name="expression" type="javascript">dataSetRow["Name"]</expression>
                    <prop name="dataType">string</prop>
                </struct>
                <struct>
                    <prop name="name">City</prop>
                    <text-prop name="displayName">City</text-prop>
                    <expression name="expression" type="javascript">dataSetRow["City"]</expression>
                    <prop name="dataType">string</prop>
                </struct>
                <structure>
                    <prop name="name">Age</prop>
                    <text-prop name="displayName">Age</text-prop>
                    <expression name="expression" type="javascript">dataSetRow["Age"]</expression>
                    <prop name="dataType">integer</prop>
                </structure>
            </list-prop>
            <column id="17"/>
            <column id="18"/>
            <column id="19"/>
            <header>
                <row id="5">
                    <cell id="6">
                        <label id="20">
                            <text-prop name="text">NameTitle</text-prop>
                        </label>
                    </cell>
                    <cell id="7">
                        <label id="21">
                            <text-prop name="text">CityTitle</text-prop>
                        </label>
                    </cell>
                    <cell id="8">
                        <label id="22">
                            <text-prop name="text">AgeTitle</text-prop>
                        </label>
                    </cell>
                </row>
            </header>
            <detail>
                <row id="9">
                    <cell id="10">
                         <data>
                            <prop name="resultSetColumn">Name</prop>
                        </data>
                    </cell>
                    <cell id="11">
                         <data>
                            <prop name="resultSetColumn">City</prop>
                        </data>
                    </cell>
                    <cell id="12">
                         <data>
                            <prop name="resultSetColumn">Age</prop>
                        </data>
                    </cell>
                </row>
            </detail>
        </table>
    </body>
</report>

注意:数据源和数据集中的encryptionIDextensionID都是固定值.

Note: The encryptionID and extensionID both in data-source and data-set are fix values.

所以基本上数据来自使用源 source1 的 set set1 ,它也直接来自 source1 ,所以我需要有从第二个 XML 文件中检索正确数据的方法.

So basically the data comes from set set1 that uses source source1, and it also comes directly from source1 , so I need to have a way of retrieving the correct data from the second XML file.

如您所见,我可以在第二个 XML 文件中有许多 layoutreport 元素.所以,首先我想我需要在第一个 XML 文件中找到 displayName 属性,然后找到 layout 元素,其中 name 属性匹配 displayName.然后,我需要在第二个 XML 文件中,通过 layout 元素中的 ID 属性,找到具有相同值的 report 元素在 layoutID 属性中.从这里开始,我会找到正确的 report 元素.直到现在我才开始更改/添加第一个 XML 文件.这部分我真的不知道该怎么做.我正在尝试做的可能吗?

As you can see, I have can have many layout and report elements in the second XML file. So, first I think I need to find the displayName property in the first XML file and then find the layout element that in which the name attribute matches displayName. Then, I need to, in the second XML file, by the ID attribute in layout element, find the report element that has that same value in the layoutID attribute. From here on I would have found the correct report element. Only now I would begin to change/make additions to the first XML file. This part I don't really know how to do. Is what I'm trying to do possible?

我知道你可以使用 document 函数来处理 2 个 XML 文件,但我真的不知道如何,

I know you can use the document function to work with 2 XML files, but I don't really know how,

我真的需要帮助伙计们,谢谢!

I really need help guys, thank you!

编辑

我基本上想复制第一个 XML 文件中的所有内容(已经完成),然后使用存储在第二个 XML 文件中的数据(以 <model> 元素

I basically want to copy everything in the first XML file (already done) and then make additions to it with data stored in the second XML file (the one that starts with the <model> element

更新

因为我希望输出是第一个输入 XML 文件的补充,所以我开始,正如@Sojimanatsu 推荐的那样,通过应用身份转换,像这样(在@TimC 的帮助下,针对特定问题的帖子特殊字符(XML - XSLT - 转义特殊字符)):

Because I want the output to be an addition to the first input XML file, I started, as @Sojimanatsu recomended, by applying an identity transformation, like this (with @TimC's help on a post for the specific problem of the the special characters (XML - XSLT - Escape special characters) ):

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xmlns:xmlbirtns="http://www.eclipse.org/birt/2005/design"
                              xpath-default-namespace="http://www.eclipse.org/birt/2005/design">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8" />
    <xsl:strip-space elements="*"/>

    <!--copy the whole input XML file-->
    <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>

    <!--special treatment for setup/text-prop element-->
   <xsl:template match="report/setup/simple-master-page/footer/text/text-prop">
     <xsl:copy>
         <xsl:attribute name="name">
             <xsl:text>content</xsl:text>
         </xsl:attribute>
         <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
         <xsl:value-of select="." disable-output-escaping="yes"/>
         <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>

      </xsl:copy>
  </xsl:template> 

</xsl:stylesheet>

注意: 处理 setup/text-prop 元素的 XSLT 代码是可选的,因为我的输出 XML 可以具有 &lt;value-of&gt;new Date()&lt;/value-of> 而不是 <![CDATA[

NOTE: The XSLT code that deals with the setup/text-prop element is optional, because my output XML can have &lt;value-of&gt;new Date()&lt;/value-of&gt; instead of <![CDATA[<value-of>new Date()</value-of>]]>

所以现在我可以在输出 XML 中打印出我在第一个输入 XML 中所拥有的内容.现在,正如@Sojimanatsu 所说,我想选择特定标签并使用来自第二个输入 XML 文件的新数据对其进行编辑,我还想添加新标签/元素,例如 data-sourcesdata-sets 元素,但我不知道该怎么做.我知道我必须使用 document() 函数,但如何使用??

So now I'm being able to print in the output XML exactly what I have in the first input XML. Now, as @Sojimanatsu said, I want to select specific tags and edit them with new data coming from the sencond input XML file, and I also want to add new tags/elements, like the data-sources and data-sets elements, but I don't know how to do this. I know I have to use the document() function but how??

首先,我如何添加一个新元素, 元素下方和 之前 元素?( 是兄弟)

To start, how can I add a new element, <data-sources> below the <report> element and before the <setup> element? (<data-sources> and <setup> are siblings)

我尝试这样做,添加一个新的:

I tried doing this, adding a new <xsl:template>:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xmlns:xmlbirtns="http://www.eclipse.org/birt/2005/design"
                              xpath-default-namespace="http://www.eclipse.org/birt/2005/design">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8" />
    <xsl:strip-space elements="*"/>

    <!--copy the whole input XML file-->
    <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>

    <!--special treatment for setup/text-prop element-->
   <xsl:template match="report/setup/simple-master-page/footer/text/text-prop">
     <xsl:copy>
         <xsl:attribute name="name">
             <xsl:text>content</xsl:text>
         </xsl:attribute>
         <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
         <xsl:value-of select="." disable-output-escaping="yes"/>
         <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>

      </xsl:copy>
  </xsl:template>

    <xsl:template match="report/text-prop">
      <xsl:copy-of select="."/>
        <dataSources>DATA SOURCE VALUE</dataSources>
    </xsl:template>

</xsl:stylesheet>

但是我得到了这个输出(dataSource 标记出现在正确的位置,但有一些我不知道是如何到达那里的属性):

But I'm getting this output (the dataSource tag comes in the correct place but with some attributes that I don't know how got there):

<?xml version="1.0" encoding="utf-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
   <text-prop name="displayName">PersonTemplate</text-prop>
   <dataSources xmlns=""
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:xmlbirtns="http://www.eclipse.org/birt/2005/design">DATA SOURCE VALUE</dataSources>
   <setup>
      <simple-master-page name="MasterPage" id="2">
         <footer>
            <text id="3">
               <prop name="contentType">html</prop>
               <text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
            </text>
         </footer>
      </simple-master-page>
   </setup>
   <body>
      <table id="4">
         <column id="17"/>
         <column id="18"/>
         <column id="19"/>
         <header>
            <row id="5">
               <cell id="6">
                  <label id="20">
                     <text-prop name="text">NameTitle</text-prop>
                  </label>
               </cell>
               <cell id="7">
                  <label id="21">
                     <text-prop name="text">CityTitle</text-prop>
                  </label>
               </cell>
               <cell id="8">
                  <label id="22">
                     <text-prop name="text">AgeTitle</text-prop>
                  </label>
               </cell>
            </row>
         </header>
         <detail>
            <row id="9">
               <cell id="10"/>
               <cell id="11"/>
               <cell id="12"/>
            </row>
         </detail>
      </table>
   </body>
</report>

我真正的第一个和第二个输入 XML 文件要大得多,但是一旦我让这个示例工作,我就可以生成我真正的 XML 输出,

My real first and second input XML files are considerably bigger but once I have this example working I can produce my real XML output,

谢谢各位!

推荐答案

我想你基本上是在寻找这个功能.

I think you are looking for this function basically.

document() 函数

所以这个函数的想法是能够选择另一个 xml 文件,并基于一些 xpath 迭代,使用该 xml 文件中的一些值,在你的新 xml 或其他任何东西中.

So the idea of this functions is to be able to select another xml file and based on some xpath iterations, use some values from that xml file, inside your new xml or whatever.

这篇关于XML - XSLT - 使用两个 XML 文件 - 参考另一个 XML 文件的 XML 文件的添加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆