XSL объединить изменить и добавить - PullRequest
1 голос
/ 05 февраля 2020

Я разработал, как объединить два файла XML и изменить соответствующий атрибут.

Сейчас я пытаюсь решить, как добавить узел file2 (на основе имени атрибута), если он это делает не существует в file1

!--File1 xml -->
<stylesheet>
<variable name="Test1" />
<variable name="Test2" select="'yy'"/>
<variable name="Test3" select="'xx'"/>
</sytlesheet>

<!--File2 xml -->
<stylesheet>
<variable name="Test" select="'x'" />
<variable name="Test2" select="'y'" />
<variable name="Test3" select="'z'" />
<variable name="Test4" select="'dd'" />
</sytlesheet>

<!--Expected xml result-->
<stylesheet>
<variable name="Test1" />
<variable name="Test" select="'x'" />
<variable name="Test2" select="'y'" />
<variable name="Test3" select="'z'" />
<variable name="Test4" select="'dd'" />
</sytlesheet>

Вот файл xsl, который у меня есть:

<xsl:param name="fileName" select="'file2'" />

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

<xsl:template match="stylesheet/variable"> 
<xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:if test="document($fileName)/stylesheet/variable[@name = current()/@name]">
        <xsl:attribute name="value">
            <xsl:value-of select="document($fileName)/stylesheet/variable[@name = current()/@name]/@select"/>
        </xsl:attribute>    
    </xsl:if>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

Я нашел Как объединить два xml файла с XSLT , но не смог понять, как применить предложенное решение к моему xsl. Кто-нибудь может помочь?

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

Вы можете сделать просто:

XSLT 1.0

<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"/>

<!-- path to file2.xml -->
<xsl:param name="file2">file2.xml</xsl:param>

<xsl:template match="/stylesheet">
    <xsl:copy>
        <!-- local items not overridden by external items -->
        <xsl:copy-of select="variable[not(@name=document($file2)/stylesheet/variable/@name)]"/>
        <!-- ALL external items (override AND add) -->
        <xsl:copy-of select="document($file2)/stylesheet/variable"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
1 голос
/ 05 февраля 2020

Похоже на задачу группирования элементов variable из обоих документов по name, а затем использования элемента last() в каждой группе, чтобы убедиться, что выводится только один элемент:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="file2">
<stylesheet>
<variable name="Test" select="'x'" />
<variable name="Test2" select="'y'" />
<variable name="Test3" select="'z'" />
<variable name="Test4" select="'dd'" />
</stylesheet>
  </xsl:param>

  <xsl:output indent="yes"/>

  <xsl:template match="stylesheet">
      <xsl:copy>
          <xsl:for-each-group select="variable, $file2/stylesheet/variable" group-by="@name">
              <xsl:copy-of select="current-group()[last()]"/>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bwe3c2 и приведенный выше фрагмент имеет вторичный ввод, встроенный для компактности и полноты примера, но вы, конечно, можете использовать <xsl:param name="file2" select="doc('file2.xml')"/> вместо этого в вашем реальном случае использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...