另一个更新一个XML
你好:我在这个问题上稍微改变了逻辑。第一个子1与字段匹配,但仅当字段1值匹配时。sub2仅与字段匹配,但没有多个值。如果可能的话,请告诉我好吗?谢谢大家!另一个更新一个XML,xml,xslt,replace,compare,Xml,Xslt,Replace,Compare,你好:我在这个问题上稍微改变了逻辑。第一个子1与字段匹配,但仅当字段1值匹配时。sub2仅与字段匹配,但没有多个值。如果可能的话,请告诉我好吗?谢谢大家! <ROOT> <OLD> <sub1> <Row> <field1>1</field1> <field2>THING1</field2>
<ROOT>
<OLD>
<sub1>
<Row>
<field1>1</field1>
<field2>THING1</field2>
<field3/>
<field4/>
<field5/>
<field6/>
<field7/>
</Row>>
<Row>
<field1>2</field1>
<field2>THING2</field2>
<field3/>
<field4/>
<field5/>
<field6/>
<field7/>
</Row>
<Row>
<field1>3</field1>
<field2>THING3</field2>
<field3/>
<field4/>
<field5/>
<field6/>
<field7/>
</Row>
</sub1>
<sub2>
<field1>BeforeTEST</field1>
<field2>That</field2>
<field3/>
<field4/>
<field5/>
<field6/>
<field7/>
<field8/>
<field9/>
<field10/>
<field11/>
<field12/>
<field13/>
<field14>Leave it</field14>
</sub2>
</OLD>
<NEW>
<sub1>
<field1>1</field1>
<field2>THING</field2>
<field3>Is bad</field3>
</sub1>
<sub2>
<field1>TEST</field1>
<field2>THIS</field2>
<field5>THAT</field5>
</sub2>
</NEW>
</ROOT>
1.
事情1
>
2.
事情2
3.
事情3
试验前
那个
别管它
1.
事情
不好
试验
这
那个
如何到达目的地
<ROOT>
<sub1>
<Row>
<field1>1</field1>
<field2>THING</field2>
<field3>Is bad</field3>
<field4/>
<field5/>
<field6/>
<field7/>
</Row>>
<Row>
<field1>2</field1>
<field2>THING2</field2>
<field3/>
<field4/>
<field5/>
<field6/>
<field7/>
</Row>
<Row>
<field1>3</field1>
<field2>THING3</field2>
<field3/>
<field4/>
<field5/>
<field6/>
<field7/>
</Row>
</sub1>
<sub2>
<Row>
<field1>TEST</field1>
<field2>THIS</field2>
<field3/>
<field4/>
<field5>THAT</field5>
<field6/>
<field7/>
<field8/>
<field9/>
<field10/>
<field11/>
<field12/>
<field13/>
<field14>Leave it</field14>
</Row>
</sub2>
</ROOT>
1.
事情
不好
>
2.
事情2
3.
事情3
试验
这
那个
别管它
假设您的基本文件用作XSLT处理器的源文件,并且名为update.xml
的文件包含替换字段,则可以使用下面的样式表替换字段
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="update-doc" select="document('update.xml')"/>
<xsl:template match="/Root">
<xsl:copy>
<xsl:apply-templates select="@*|*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Root/*">
<xsl:variable name="sub-name" select="name(.)"/>
<xsl:copy>
<xsl:for-each select="*">
<xsl:variable name="base-field" select="."/>
<xsl:copy>
<xsl:if test="not($update-doc/Root/*[name() = $sub-name]/*[name() = name($base-field)])">
<xsl:value-of select="."/>
</xsl:if>
<xsl:for-each select="$update-doc/Root/*[name() = $sub-name]/*">
<xsl:variable name="replacement-field" select="."/>
<xsl:if test="name($base-field) = name($replacement-field)">
<xsl:value-of select="$replacement-field"/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果某个字段存在于基础文档中而不存在于更新文档中,则该字段将被保留,否则将被覆盖
更新由于您更改了需求,现在您希望将数据保存在一个文件中,因此我根据您的新格式调整了样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/Root">
<xsl:copy>
<xsl:apply-templates select="@*|OLD"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OLD/*">
<xsl:variable name="sub-name" select="name(.)"/>
<xsl:copy>
<xsl:for-each select="*[ancestor::OLD]">
<xsl:variable name="base-field" select="."/>
<xsl:copy>
<xsl:if test="not(//NEW/*[name() = $sub-name]/*[name() = name($base-field)])">
<xsl:value-of select="."/>
</xsl:if>
<xsl:for-each select="//NEW/*[name() = $sub-name]/*">
<xsl:variable name="replacement-field" select="."/>
<xsl:if test="name($base-field) = name($replacement-field)">
<xsl:value-of select="$replacement-field"/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我认为
,
等的名称将事先不知道。不过,如果您可以信任ROOT/OLD/*/*
的基本结构和相应的ROOT/NEW/*/*/*
,您可以这样做:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="update" match="NEW/*/*" use="concat(name(parent::*), '/', name())" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OLD">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="OLD/*/*[key('update', concat(name(parent::*), '/', name()))]">
<xsl:copy-of select="key('update', concat(name(parent::*), '/', name()))"/>
</xsl:template>
<xsl:template match="NEW"/>
</xsl:stylesheet>
请注意,您事先对XML结构了解得越多,在选择/匹配节点时就越明确,转换过程也就越有效 你说的“更新”到底是什么意思?XSLT本身不会修改源文档。不会更新。。只需创建结果XML,并将expect信息作为输出。但是,您是否只是将输入更改为单个文件?那会有很大的不同。你好,迈克尔。太棒了,谢谢你。让一个牧场陷入困境。如果子1段重复多次,并且仅当新旧字段1值相同时才需要匹配。您好,Michael。。我只是更新了原来的帖子。。这比我最初经历的要复杂得多。我真的很感谢你在这方面的帮助!谢谢大家!@用户3379902您确定这就是确切的结构吗?这似乎并不一致。也很难理解转换背后的逻辑(假设存在这种逻辑)。