gpt4 book ai didi

xml - xsltproc 合并 xml 文件不起作用

转载 作者:太空狗 更新时间:2023-10-29 12:39:38 30 4
gpt4 key购买 nike

您好,我必须在以下条件下合并 xml 文件:

复制新文件的所有现有节点,然后与旧文件值合并。例如:

文件 abc.xml

<?xml version="1.0"?>
<schedule>
<Item Id="2">
<measurements>
<measurement>Alpha</measurement>
</measurements>
</Item>
<Item Id="9">
<measurements>
<measurement>Gamma</measurement>
</measurements>
</Item>
</schedule>

文件 xyz.xml

<?xml version="1.0"?>
<schedule>
<Item Id="1">
<measurements>
<measurement>Alpha</measurement>
</measurements>
</Item>
<Item Id="4">
<measurements>
<measurement>Beta</measurement>
</measurements>
</Item>
</schedule>

xslt逻辑文件:逻辑.xslt

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

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

<xsl:template match="Item">
<xsl:variable name="match" select="document('./abc.xml')/schedule/Item[measurements/measurement=current()/measurements/measurement]"/>
<xsl:choose>
<xsl:when test="$match">
<xsl:copy-of select="$match"/>
</xsl:when>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

使用的命令:

xsltproc logic.xslt xyz.xml > output.xml

预期输出:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schedule>
<Item Id="2">
<measurements>
<measurement>Alpha</measurement>
</measurements>
</Item>
<Item Id="4">
<measurements>
<measurement>Beta</measurement>
</measurements>
</Item>
<Item Id="9">
<measurements>
<measurement>Gamma</measurement>
</measurements>
</Item>
</schedule>

但实际情况与预期不同,如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schedule>
<Item Id="2">
<measurements>
<measurement>Alpha</measurement>
</measurements>
</Item>
<Item Id="9">
<measurements>
<measurement>Gamma</measurement>
</measurements>
</Item>
</schedule>

它遗漏了新 xml 文件中的节点。

最佳答案

改变

<xsl:choose>
<xsl:when test="$match">
<xsl:copy-of select="$match"/>
</xsl:when>
</xsl:choose>

<xsl:choose>
<xsl:when test="$match">
<xsl:copy-of select="$match"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:choose>

随着问题的编辑和需要复制的第二个文档中的其他元素,我认为这个问题更加困难,使用 XSLT 3 你可以像 https://xsltfiddle.liberty-development.net/pPqsHTf 中那样做

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">

<xsl:mode on-no-match="shallow-copy"/>

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:param name="doc1" select="/"/>

<xsl:param name="doc2">
<schedule>
<Item Id="2">
<measurements>
<measurement>Alpha</measurement>
</measurements>
</Item>
<Item Id="9">
<measurements>
<measurement>Gamma</measurement>
</measurements>
</Item>
</schedule>
</xsl:param>

<xsl:key name="ref" match="Item" use="measurements/measurement"/>

<xsl:template match="schedule">
<xsl:copy>
<xsl:apply-templates select="Item, $doc2/schedule/Item[not(key('ref', measurements/measurement, $doc1))]"/>
</xsl:copy>
</xsl:template>

<xsl:template match="Item[root() is $doc1 and key('ref', measurements/measurement, $doc2)]">
<xsl:copy-of select="key('ref', measurements/measurement, $doc2)"/>
</xsl:template>

</xsl:stylesheet>

(当然,您可以使用 <xsl:param name="doc2" select="document('abc.xml')"/> 来代替内联第二个文档)但是对于 XSLT 1,使用变量和键会更加困难,并且您不能在匹配模式中使用它们,因此似乎需要一种方法如 https://xsltfiddle.liberty-development.net/pPqsHTf/2

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">


<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:param name="doc1" select="/"/>

<xsl:param name="doc2-rtf">
<schedule>
<Item Id="2">
<measurements>
<measurement>Alpha</measurement>
</measurements>
</Item>
<Item Id="9">
<measurements>
<measurement>Gamma</measurement>
</measurements>
</Item>
</schedule>
</xsl:param>

<xsl:param name="doc2" select="exsl:node-set($doc2-rtf)" xmlns:exsl="http://exslt.org/common"/>

<xsl:template match="schedule">
<xsl:copy>
<xsl:apply-templates select="Item"/>
<xsl:copy-of select="$doc2/schedule/Item[not(measurements/measurement = $doc1//Item/measurements/measurement)]"/>
</xsl:copy>
</xsl:template>

<xsl:template match="Item">
<xsl:choose>
<xsl:when test="measurements/measurement = $doc2//Item/measurements/measurement">
<xsl:copy-of select="$doc2//Item[measurements/measurement = current()/measurements/measurement]"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

当然再次简单地使用<xsl:param name="doc2" select="document('abc.xml')"/>而不是让数据内联(我只做了一个完整的例子,不幸的是,XSLT 1 需要使用节点集扩展函数)。

关于xml - xsltproc 合并 xml 文件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50445540/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com