查找 XML 属性值并将其替换为另一个文件 [英] Find and replace XML attribute values from one file to another

查看:32
本文介绍了查找 XML 属性值并将其替换为另一个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 2 个 XML 文件,其中包含有关相同项目的数据,它们保存在客户端和服务器上.与服务器相比,客户端上的某些数据是相同的,某些属性/子元素是不同的.

客户数据看起来像这样(有更多与比较无关的属性):

<text1>样本</text1><icon>iconurl</icon></项目>

服务器数据如下所示(具有更多属性和可能的​​子元素):

</项目>

因为项目的匹配是通过我们代码中的 ID 完成的,为 server.xml 输入数据的人对名称不是很小心,留下了拼写错误或占位符名称.这不会导致错误,但是我希望安全起见,并确保将 server.xml 中所有拼写错误的条目替换为 client.xml 中的正确名称(这些名称经过双重检查并且都是正确的)

是否可以运行一些脚本/代码/xslt 样式表来将 server.xml 中的名称替换为来自 client.xml 的名称?

我对样式表不是很熟悉,也不知道从哪里开始编写类似的代码

基本上我希望它看起来像这样:

读取client.xml读取 server.xml对于 client.xml 中的每个项目,读取属性id"和name"在 server.xml 中查找具有相同id"的项目将 server.xml 中的name"替换为 client.xml 中具有该id"的项目的值

感谢您提供的任何帮助

解决方案

您可以在此处使用 document 函数,从第二个文档(在您的情况下为client.xml")中查找信息') 将 XSLT 应用到 server.xml 时

例如,您可以定义一个变量,如包含 client.xml 中的所有 item 元素

然后,要替换 server.xml 中的 @name 属性,您可以创建一个模板来匹配这些属性,并改为从 client.xml 输出值.

<xsl:attribute name="name"><xsl:value-of select="$client[@id=current()/../@id]/@name"/></xsl:attribute></xsl:模板>

这是完整的 XSLT

<xsl:output method="xml" indent="yes"/><xsl:param name="clientXml" select="'client.xml'"/><xsl:variable name="client" select="document($clientXml)//item"/><xsl:template match="item/@name"><xsl:attribute name="name"><xsl:value-of select="$client[@id=current()/../@id]/@name"/></xsl:attribute></xsl:模板><xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:模板></xsl:stylesheet>

当应用于您的示例 client.xml 和 server.xml 文档时,输出如下

请注意,我已经参数化了client.xml"文档的名称,因为这将允许您在需要时对不同命名的文档使用 XSLT.您只需将第二个 XML 文件的名称作为参数传递即可.

I have 2 XML files with data about same items, that are kept on client and server. Some of the data are the same, some attributes/sub-elements are different on client compared to server.

Client data look like this (with more attributes that are irrelevant to the comparison):

<item id="1" create_dttm="05/28/2010 12:00:00 AM" name="Correct_Name">
        <text1>sample</text1>
        <icon>iconurl</icon>        
</item>

Server data look like this (with more attributes and possible sub-elements):

<item type="4" id="1" name="mispelled_name">
</item> 

Because matching for the items is done via the ID in our code, people that did data entry for the server.xml were not very careful with the names, leaving in typos or placeholder names. This does not cause bugs, however i would prefer to be on the safe side and make sure all the misspelled entries in server.xml to be replaced by correct names from the client.xml (those are double checked and are all correct)

Is it possible to run some script/code/xslt stylesheet to replace the names in the server.xml with the names from the client.xml?

I am not very familiar with stylesheets and not sure where to begin with coding something like that

Basically i want it to look like this:

Read client.xml
Read server.xml

For each item in client.xml, read attributes "id" and "name"
find item with same "id" in server.xml
replace "name" in server.xml with value from client.xml for the item with that "id"

Thank you for any help you can provide

解决方案

You could make use of the document function here, to look up information from a second document (in your case 'client.xml') when applying the XSLT to server.xml

For example, you could define a variable like, to contain all the item elements in client.xml

<xsl:variable name="client" select="document('client.xml')//item" />

Then, to replace the @name attributes in server.xml, you could create a template to match the attributes, and output the values from client.xml instead.

<xsl:template match="item/@name">
    <xsl:attribute name="name">
        <xsl:value-of select="$client[@id=current()/../@id]/@name" />
    </xsl:attribute>
</xsl:template>

Here is the full XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:param name="clientXml" select="'client.xml'" />

    <xsl:variable name="client" select="document($clientXml)//item" />

    <xsl:template match="item/@name">
        <xsl:attribute name="name">
            <xsl:value-of select="$client[@id=current()/../@id]/@name" />
        </xsl:attribute>
    </xsl:template>

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

When applied to your sample client.xml and server.xml documents, the following is output

<item type="4" id="1" name="Correct_Name"></item>

Note that I have parameterised the name of the 'client.xml' document, as this would allow you to use the XSLT on differently named documents if required. You would just have to pass the name of the second XML file as a parameter.

这篇关于查找 XML 属性值并将其替换为另一个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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