【发布时间】:2018-07-05 22:53:26
【问题描述】:
我有以下问题,对我来说,有点棘手,
基本上我需要能够使用存储在另一个 XML 文件中的数据来修改一个 XML 输入文件,所以我必须使用 2 个输入 XML 文件,
我有以下 XML 文件,这是我要修改的文件(基本上,只是对其进行添加):
<?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 文件的数据:
<?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 文件:
<?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>
注意: data-source 和 data-set 中的 encryptionID 和 extensionID 都是固定值。
所以基本上数据来自使用源source1 的集合set1,它也直接来自source1,所以我需要一种从第二个XML 文件中检索正确数据的方法。
如您所见,我可以在第二个 XML 文件中包含许多 layout 和 report 元素。所以,首先我想我需要在第一个 XML 文件中找到displayName 属性,然后找到name 属性与displayName 匹配的layout 元素。然后,我需要在第二个 XML 文件中,通过 layout 元素中的 ID 属性,找到在 layoutID 属性中具有相同值的 report 元素。从这里开始,我会找到正确的report 元素。直到现在我才开始更改/添加第一个 XML 文件。这部分我真的不知道该怎么做。我正在尝试做的事情可能吗?
我知道你可以使用 document 函数来处理 2 个 XML 文件,但我真的不知道如何,
我真的需要帮助,谢谢!
编辑
我基本上想复制第一个 XML 文件中的所有内容(已经完成),然后使用存储在第二个 XML 文件(以 <model> 元素开头的那个)中的数据进行添加
更新
因为我希望输出是第一个输入 XML 文件的补充,所以我开始按照@Sojimanatsu 的建议,通过应用身份转换,像这样(在@TimC 的帮助下针对特定问题的帖子特殊字符(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"><![CDATA[</xsl:text>
<xsl:value-of select="." disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意:处理 setup/text-prop 元素的 XSLT 代码是可选的,因为我的输出 XML 可以有 &lt;value-of&gt;new Date()&lt;/value-of&gt; 而不是 <![CDATA[<value-of>new Date()</value-of>]]>
所以现在我能够在输出 XML 中准确地打印我在第一个输入 XML 中的内容。现在,正如@Sojimanatsu 所说,我想选择特定标签并使用来自第二个输入 XML 文件的新数据对其进行编辑,并且我还想添加新标签/元素,例如 data-sources 和 data-sets 元素,但是我不知道该怎么做。我知道我必须使用 document() 函数但是如何使用??
首先,如何在<report> 元素下方和<setup> 元素之前添加一个新元素<data-sources>? (<data-sources> 和 <setup> 是兄弟姐妹)
我试过这样做,添加一个新的<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"><![CDATA[</xsl:text>
<xsl:value-of select="." disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes">]]></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 标记出现在正确的位置,但有一些我不知道如何到达那里的属性):
<?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 输出,
谢谢大家!
【问题讨论】: