XSLT на отчете о SSRS

Как насчет того, чтобы использовать этот "дополнительный" метод на XElement? работавший для меня!

public static string InnerXml(this XElement element)
{
    StringBuilder innerXml = new StringBuilder();

    foreach (XNode node in element.Nodes())
    {
        // append node's xml string to innerXml
        innerXml.Append(node.ToString());
    }

    return innerXml.ToString();
}

ИЛИ использование определенное примечание Linq

public static string InnerXml(this XElement element)
{
    StringBuilder innerXml = new StringBuilder();
    doc.Nodes().ToList().ForEach( node => innerXml.Append(node.ToString()));

    return innerXml.ToString();
}

: код выше должен использовать element.Nodes() в противоположность element.Elements(). Очень важная вещь помнить различие между двумя. element.Nodes() дает Вам все как XText, XAttribute и т.д., но XElement только Элемент.

5
задан Deduplicator 1 February 2015 в 14:22
поделиться

6 ответов

Из-за Microsoft Пространство имен SQL Reporting Services 2008, которое было частью входного XML. Сначала я не понял, что был таким важная линия. Спасибо Павлу Минаеву за комментарий к пространству имен . Следующий XSL работал для извлечения данных, которые мне нужны:

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

  <xsl:template match="/">
    <xsl:for-each select="a:Report/a:FlatData/a:Details1_Collection/a:Details1">
      <xsl:element name="{name(.)}">
        <xsl:for-each select="@*">
          <xsl:element name="{name(.)}">
            <xsl:value-of select="."/>
          </xsl:element>
        </xsl:for-each>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Я думаю, я попытаюсь очистить это, чтобы использовать стиль apply-templates , который предложил lavinio . Также благодарим Йорна Хорстманна за select = "@ *" Код в для каждого цикла. Было бы интересно выяснить, почему отчеты служб Reporting Services изначально выгружаются со значением xmlns , установленным в качестве имени отчета, а не URL схемы .

Я продолжайте обновлять этот ответ по мере того, как я уточняю этот XSL.

Изменить: вот версия, не зависящая от пространства имен, поскольку для каждого отдельного отчета из служб Reporting Services, очевидно, будет другое пространство имен:

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

  <xsl:template match="/">
    <xsl:for-each select="*[local-name()='Report']/*[local-name()='FlatData']/*[local-name()='Details1_Collection']/*[local-name()='Details1']">
      <Details>
        <xsl:for-each select="@*">
          <xsl:element name="{name(.)}">
            <xsl:value-of select="."/>
          </xsl:element>
        </xsl:for-each>
      </Details>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
4
ответ дан 13 December 2019 в 05:40
поделиться

Чтобы решить проблему пространства имен (для обоих ответов), добавьте объявление пространства имен с префиксом в свой XLST:

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

, а затем используйте его во всех своих выражениях XPath для определения элементов, например:

<xsl:template match="//r:Details1">
3
ответ дан 13 December 2019 в 05:40
поделиться

Вы можете использовать "@ *" для ссылки на все атрибуты, как в этих примерах:

Конструкция может использоваться для создания новый элемент с произвольным именем, а функции name () или local-name () вернут имя определенного атрибута.

Чтобы сделать то, что вы хотите, попробуйте что-то вроде этих строк:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <FlatData>
            <Details1_Collection>
                <xsl:apply-templates select="FlatData/Details1_Collection/Details1"/>
            </Details1_Collection>
        </FlatData>
    </xsl:template>
    <xsl:template match="Details1">
        <Details1>
            <xsl:apply-templates select="@*"/>
        </Details1>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:element name="{name()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
3
ответ дан 13 December 2019 в 05:40
поделиться

Дает ли это преобразование желаемый результат?

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

    <xsl:output method="xml" indent="yes" encoding="utf-8" />

    <xsl:template match="//Details1">
        <Details1>
            <xsl:for-each select="@*">
                <xsl:element name="{name(.)}"><xsl:value-of select="." /></xsl:element>
            </xsl:for-each>
        </Details1>
    </xsl:template>

</xsl:stylesheet>
2
ответ дан 13 December 2019 в 05:40
поделиться

Наверное, самый простой способ сделать это:

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

  <xsl:template match="/">
    <FlatData>
      <xsl:copy-of select="//Details1" />
    </FlatData>
  </xsl:template>
</xsl:stylesheet>
0
ответ дан 13 December 2019 в 05:40
поделиться

Другой способ написать ответ Йорна Хорстманна (если вам нужно сделать это с помощью Details1, Details2 и т. Д. ...) будет:

<xsl:template match="//Details1 | //Details2 | //whatever">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="@*">
  <xsl:element name="{name(.)}">
    <xsl:value-of select="." />
  </xsl:element>
</xsl:template>
0
ответ дан 13 December 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: