преобразование 2 xml файлов из 1 xslt - PullRequest
0 голосов
/ 31 января 2019

Я искал в темах похожие посты, и хотя некоторые из них близки, мне трудно понять.

Мне нужно преобразовать 2 файла xml из 1 xslt.Вот что у меня есть:

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>

вторичный.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 все, что относится к файл second.xml, основной файлXML преобразуется.Я запутался в 1.), включая файл second.xml.Имеет ли значение, где эта ссылка находится внутри xslt?2.) Я не понимаю, как передать переменную из primary.xml в Secondary.xml.

Я прочитал так много статей за последние два дня, ... Я сейчас более растерян, чем когда я начинал.Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 01 февраля 2019

включая файл second.xml.Имеет ли значение, где эта ссылка встречается в xslt?

Это может произойти где угодно, даже на корневом уровне.Но его определение, например, в шаблоне ограничивает его использование соответствующей областью (если не передано с параметром).

Значение элемента FKey будет иметь значение, совпадающее с первичнымXML-файл.

Это можно сделать с помощью простого выражения предиката.Здесь я выбрал

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

, который выбирает узел bobo из вторичного XML-файла, значение FKey которого совпадает с переменной ID.

I'mзапутался в том, как передать переменную из primary.xml в primary.xml.

Нет.Оба XML-файла доступны из одного и того же XSLT.Но вы забыли добавить 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>

Вывод не очень красивый,но я думаю, вы легко можете позаботиться об этом сами.

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