从1个xslt转换2个xml文件

时间:2019-01-31 20:49:49

标签: xml xslt

我已经在线程中搜索了类似的帖子,尽管有些帖子很接近,但我很难理解。

我需要从1 xslt转换2个xml文件。这是我所拥有的:

primary.xml

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <bobo ID="123">
      <FirstName>Oscar</FirstName>
      <LastName>Bologna</LastName>
      <Address>1 Sandwich Street</Address>
      <City>Pickle Juice</City>
      <State>DE</State>
      <Zip>12345</Zip>
  </bobo>
  <bobo ID="124">
      <FirstName>Suzie</FirstName>
      <LastName>Que</LastName>
      <Address>1 Makeup Lane</Address>
      <City>Makeupville</City>
      <State>DE</State>
      <Zip>12346</Zip>
  </bobo>
</root>

secondary.xml-FKey元素的值将与primary.xml文件中的匹配。

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <bobo ID="789">
      <FKey>123</FKey>
      <HomePhone>(123) 456-7890</HomePhone>
      <MobilePhone>(123) 456-7899</MobilePhone>
      <Fax>(123) 456-7898</Fax>
  </bobo>
  <bobo ID="790">
      <FKey>124</FKey>
      <HomePhone>(123) 456-1234</HomePhone>
      <MobilePhone>(123) 456-1233</MobilePhone>
      <Fax>(123) 456-1235</Fax>
  </bobo>
</root>

这是我对xslt的微弱尝试:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
  <xsl:template match="/">

    <xsl:for-each select="root/bobo">
      <xsl:variable name="ID" select="@ID" />
      <xsl:variable name="xmlDoc" select="document('subfolder/secondary.xml')"/>

      <xsl:value-of select="FirstName"/> <xsl:value-of select="LastName"/><br />
      <xsl:value-of select="Address"/><br />
      <xsl:value-of select="City"/>, <xsl:value-of select="State"/>  <xsl:value-of select="Zip"/><br />

      <xsl:call-template name="Phones">
        <xsl:with-param name="FKey" select="$ID" />
      </xsl:call-template>

      </xsl:for-each>
</xsl:template>

  <xsl:template name="Phones" match="/">
    <xsl:for-each select="root/bobo">
      <xsl:choose>
        <xsl:when test="FKey='$ID'">

          Ph. <xsl:value-of select="HomePhone"/><br />
          Cell <xsl:value-of select="MobilePhone"/><br />
          Fax <xsl:value-of select="Fax"/><br /><br />

        </xsl:when>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

首先,如果我删除了xslt中与secondary.xml相关的所有内容,则primary.xml会被转换。我对1.)包括secondary.xml文件感到困惑。这个引用在xslt中出现的位置有关系吗? 2.)我对如何将变量从primary.xml传递到secondary.xml感到困惑。

过去两天我读了很多文章,...现在我比开始时更加困惑。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

  

包括secondary.xml文件。此引用在xslt中出现的位置有关系吗?

它可以发生在任何地方,即使在根级别。但是在例如模板中对其进行定义会将其用法限制在相应的范围内(除非通过参数传递)。

  

FKey元素的值将与primary.xml文件中的匹配。

您可以使用简单的谓词表达式来执行此操作。在这里我选择了

$secondXmlDoc/root/bobo[FKey=$ID]

从辅助XML文件中选择bobo值与FKey变量相同的ID节点。

  

我对如何将变量从primary.xml传递到secondary.xml感到困惑。

你不知道。可以从同一XSLT访问这两个XML文件。但是您忘记在行中添加xsl:param...

<xsl:template name="Phones" match="/">
  <xsl:param name="FKey">
  ...
目标模板中的

。顺便说一句,将参数命名为与节点相同可能不是一个好主意-可能会造成混乱。


作为一个整体,XSLT-1.0模板可能如下所示。我将document(...)指令放在顶层,以便您可以从XSLT文件中的任何位置访问它。我删除了call-template,因为它不是必需的。如果需要,请确保在目标模板中添加一个xsl:param...来接收参数(在上面的代码中未这样做)。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
  <xsl:variable name="secondXmlDoc" select="document('subfolder/secondary.xml')"/>

  <xsl:template match="/root">
    <xsl:for-each select="bobo">
      <xsl:variable name="ID" select="@ID" />

      <xsl:value-of select="FirstName"/> <xsl:value-of select="LastName"/><br />
      <xsl:value-of select="Address"/><br />
      <xsl:value-of select="City"/>, <xsl:value-of select="State"/>  <xsl:value-of select="Zip"/><br />
      <xsl:variable name="secBobo" select="$secondXmlDoc/root/bobo[FKey=$ID]" />
      <xsl:if test="$secBobo">         <!-- Check if there is a matching entry in seconday.xml -->

          Ph. <xsl:value-of select="$secBobo/HomePhone"/><br />
          Cell <xsl:value-of select="$secBobo/MobilePhone"/><br />
          Fax <xsl:value-of select="$secBobo/Fax"/><br /><br />

      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

输出效果不佳,但是我想您可以轻松地自己解决这个问题。