XSL / JScript разница в поведении между Visual Studio и IE - PullRequest
1 голос
/ 23 мая 2011

Может кто-нибудь сказать мне, почему следующий XSL успешно преобразует XML ниже в IE9, но такое же преобразование завершается неудачно во всех версиях Visual Studio? Если я открою файл XML в IE 9, он преобразуется, и результат будет таким, как ожидалось, но если я попытаюсь сделать то же преобразование в файле XML в Visual Studio (используя кнопку «Начать XSLT» на панели инструментов), я получу исключение JScriptException функция произнесения ожидается на линии

var node = root.nextNode();

Исправление, по-видимому, заключается в изменении функции javascript для выполнения следующих действий:

function test(root, attr)
{
  root.MoveNext();
  var node = root.Current;
  return node.Select("breakfast" + attr);
}

Но тогда это не дает XSLT-преобразования в IE! Я не могу победить!

XSL:

<!--<?xml version="1.0"?>-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:custom-scripts">
<msxsl:script language="JScript" implements-prefix="user">
  <![CDATA[
function test(root, attr)
{
  var node = root.nextNode();
  return node.selectSingleNode("breakfast" + attr);
}
]]>
</msxsl:script>
  <xsl:template match="/">
    <HTML>
      <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
            background-color:#EEEEEE">
          <xsl:value-of select="user:test(., '-menu')"/>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

Целевой XML:

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="simple.xsl" ?>
<breakfast-menu>
  <food>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>Two of our famous Belgian Waffles 
      with plenty of real maple syrup.</description>
    <calories>650</calories>
  </food>
  <food>
    <name>Homestyle Breakfast</name>
    <price>$6.95</price>
    <description>Two eggs, bacon or sausage, toast, 
      and our ever-popular hash browns.</description>
    <calories>950</calories>
  </food>
</breakfast-menu>

Ответы [ 3 ]

2 голосов
/ 23 мая 2011

Ну, IE использует MSXML в качестве своего XSLT-процессора (я думаю, что IE 9 использует MSXML 6), тогда как Visual Studio использует XslCompiledTransform. API-интерфейсы, предоставляемые и используемые с MSXML и XslCompiledTransform, значительно различаются, поэтому не ожидайте, что код функции расширения, написанный для MSXML API, будет работать с XslCompiledTransform и .NET API. См. http://msdn.microsoft.com/en-us/library/wxaw5z5e.aspx о том, как типы XSLT / XPath отображаются на типы .NET при использовании функций расширения. В вашем случае вы передаете набор узлов и строку из XSLT, которая сопоставляется с XPathNodeIterator и строкой в ​​.NET. Вот быстрая попытка переписать вашу функцию расширения для .NET:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:custom-scripts">
  <msxsl:script language="JScript" implements-prefix="user">
    <![CDATA[
function test(nodeIterator, string)
{
  nodeIterator.MoveNext();
  return nodeIterator.Current.SelectSingleNode("breakfast" + string);
}
]]>
  </msxsl:script>
  <xsl:template match="/">
    <HTML>
      <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
            background-color:#EEEEEE">
        <xsl:value-of select="user:test(., '-menu')"/>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

[править] Упс, я упустил, что вы уже нашли код .NET сами и хотите знать, как писать код для обоих процессоров XSLT. Это сложно. Какова ваша целевая платформа и ваша цель, вы хотите написать XSLT для IE, но разрабатывать с VS? Или вам действительно нужно использовать одну и ту же таблицу стилей в IE и на платформе .NET?

Вот попытка написать одну функцию расширения для обоих типов процессоров:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:custom-scripts">
  <msxsl:script language="JScript" implements-prefix="user">
    <![CDATA[
function test(nodeSet, string)
{
  if (typeof nodeSet.nextNode !== 'undefined') {
    var node = nodeSet.nextNode();
    return node.selectSingleNode('breakfast' + string);
  }
  else if (typeof nodeSet.MoveNext !== 'undefined') {
    nodeSet.MoveNext();
    return nodeSet.Current.SelectSingleNode("breakfast" + string);
  }
}
]]>
  </msxsl:script>
  <xsl:template match="/">
    <HTML>
      <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
            background-color:#EEEEEE">
        <xsl:value-of select="user:test(., '-menu')"/>
      </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>
1 голос
/ 23 мая 2011

Интересно, будет ли этот ответ на ТА актуален? IE9 selectSingleNode отсутствует в бета-версии, как преодолеть это в JavaScript?

1 голос
/ 23 мая 2011

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

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

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