Muenchian Grouping - отображать базу второго уровня по количеству строк

С помощью Тима из моего предыдущего поста я смог заставить мюнхенскую группировку работать для моего теста xml/xsl. Но во время работы с моим настоящим XML я столкнулся с другим сценарием, как показано ниже. Входной XML выглядит так, уменьшил его для простоты. Как вы видите <name>Status</name> <value>Existing</value> Есть много других записей в реальном XML.

<message>
<requisition>
<data-values>
    <data-value multi-valued="false">
        <name>Test_Grid-1.Name</name> <value>1</value>
    </data-value>
    <data-value multi-valued="false">
        <name>Test_Grid-1.SupportType</name> <value>Monthly,Quarterly</value>
    </data-value>
    <data-value multi-valued="false">
        <name>Test_Grid-2.Name</name> <value>2</value>
    </data-value>
    <data-value multi-valued="false">
        <name>Test_Grid-2.SupportType</name> <value>Monthly</value>
    </data-value>
    <data-value multi-valued="false">
        <name>Status</name> <value>Existing</value>
    </data-value>
</data-values>
</requisition>
<agent-parameter multi-valued="false">
  <name>ActionType</name> <value>New</value>
</agent-parameter>
<agent-parameter multi-valued="false">
  <name>Dictionary</name> <value>Test_Grid</value>
</agent-parameter>
<agent-parameter multi-valued="false">
  <name>ActionName</name> <value>SupportData</value>
</agent-parameter>
</message>

XSL, который я использую:

<xsl:key name="record" match="data-value" use="substring-before(name, '.')" />

<xsl:template match="message">
  <record>
    <xsl:apply-templates select="//data-value[generate-id() = generate-id(key('record', substring-before(name, '.'))[1])]" mode="record" />
  </record>
</xsl:template>
<xsl:template match="data-value" mode="record">
<rowData>
  <name><xsl:value-of select="$ServiceItemName" /></name>
 <xsl:apply-templates select="key('record', substring-before(name, '.'))" />
</rowData>
</xsl:template>

<xsl:template match="data-value">
 <xsl:if test="starts-with(name,concat($Dictionary,'-'))">
   <rowAttribute name="{substring-after(name, '.')}"><xsl:value-of select="value" />   </rowAttribute>
 </xsl:if>
</xsl:template>

Фактический входной xml содержит разные значения данных (кроме Test_Grid-1 или Test_Grid-2 и т. Д.). В этом сценарии XSL вытягивает все эти элементы и показывает внутри. Есть ли способ, которым я могу фильтровать значения только начиная с "Test_Grid-" (у меня есть параметр агента с именем Dictionary и значение как "Test_Grid") и xsl будет тянуть только те значения данных, где имя начинается с concat($Dictionary,'-'), Я пробовал что-то вроде ниже

       <xsl:template match="data-value">
    <xsl:if test="starts-with(name,concat($Dictionary,'-'))">
        <rowAttribute name="{substring-after(name, '.')}"><xsl:value-of select="value" /></rowAttribute>
    </xsl:if>

Но он показывает пустые элементы в выводе, как показано ниже, вместе с требуемым выводом.

 <record>
            <name>SupportData</ext:name>
 </record>
 <record>
              <name>SupportData</name>
    <rowData>
              <rowAttribute name="Name">Record1</rowAttribute>
              <rowAttribute name="SupportType">Quarterly</rowAttribute>
    </rowData>        
 </record>

Есть ли способ, которым я могу показать элемент, только когда он имеет некоторые элементы rowData в нем.

Любая помощь будет по достоинству оценена.

1 ответ

Чтобы игнорировать элементы значения данных, чьи имена не начинаются с "Test_Grid-", вы можете использовать функцию xpath "старт-с". Вы можете добавить условие к выражению xpath для фильтрации элементов data-value

data-value[starts-with(name, 'Test_Grid-')]

Фактически вы можете добавить это к совпадению xsl:key для data-value или к xsl:apply-templates, где вы их выбираете. Например, вы можете сделать это:

<xsl:key name="record" match="data-value[starts-with(name, 'Test_Grid-')]" use="substring-before(name, '.')" />

Или, альтернативно, вы можете сделать это

<xsl:apply-templates 
    select="requisition/data-values/data-value
       [starts-with(name, 'Test_Grid-')]
       [generate-id() = generate-id(key('record', substring-before(name, '.'))[1])]" 
    mode="record" />

Это может быть более эффективным, чтобы поставить его как часть ключа. Помещая его как часть ключа, проверка на наличие отдельных элементов будет учитывать только те, которые начинаются с "Test-Grid-".

Другие вопросы по тегам