2014-11-03 13 views
0

У меня есть этот XML:XSL группы не пустые элементы

<Row> 

<one>1</one> 
<two>2</two> 
<tree>3</tree> 
<four>4</four> 
<five></five> 
<six></six> 
<seven></seven> 

</Row> 

Ожидаемый XML:

<tree>3</tree> 
<four>4</four> 

Я хочу, чтобы игнорировать все элементы и группы от моего состояния.

Мой XSL является:

<xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Row"> 
      <xsl:apply-templates select="*[not(self::one or self::two)] and *[not(node())] "/> 
    </xsl:template> 

Но я получаю пустой XML.

+0

Как это группирование непустых элементов? Элементы 'one' и' two' также содержат текст, но не отображаются в ожидаемом выводе. –

+0

Я хочу получить все непустые элементы, а не один и два. поэтому мы уехали с деревом и четырьмя – lshaked

ответ

0

Если я использую ваш комментарий в качестве вашей цели: «Я хочу получить все непустые элементы, а не один и два, поэтому мы оставили дерево и четыре», вам нужно исправить свой Xpath, чтобы достичь этого , «[not (node ​​())]» исключает каждый узел() с узлом() как дочерний, но node() также выбирает текстовые узлы, поэтому вы ничего не получаете. Если вы хотите отфильтровать только элементы с элементами как дочерние, используйте ''. Таким образом, этот шаблон для строки должны выполнять работу (не проверено):

<xsl:template match="Row"> 
     <xsl:apply-templates select="*[not(self::one or self::two) and not(* or text() ='')] "/> 
</xsl:template> 
0

Что эта строка из исходного кода (я немного изменил его, так как вы не можете иметь ] появляться в середине предиката):

<xsl:apply-templates select="*[not(self::one or self::two) and not(node())] "/> 

делает, на простом английском языке:

Применение шаблонов для элементов, но только если они не являются one элементов, или если они не являются элементами two и только если они не содержат дочерний узел.

Но, конечно, вы хотели бы выбрать точную противоположность, то есть элементы, содержащие текст.

На мой взгляд, использование разных шаблонов для этой задачи было бы более чистым решением.

стилевых

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

    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <!--Traverse the Row element--> 
    <xsl:template match="Row"> 
     <xsl:apply-templates /> 
    </xsl:template> 

    <!--Do not apply templates to one, two or empty elements--> 
    <xsl:template match="Row/*[self::one or self::two or not(text())]"/> 

</xsl:stylesheet> 

XML Output

Обратите внимание, что вы не выводит хорошо сформированный XML-документ. Но это был бы действительный XML фрагмент.

<tree>3</tree> 
<four>4</four> 
0

Я получил код, который работает:, наконец

<xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Row"> 
      <xsl:apply-templates select="*[not(normalize-space()='') and not (self::one or self::two)] "/> 
    </xsl:template> 

обратите внимание, что not(normalize-space()='') должно быть в начале логического предложения.

это приведет:

<tree>3</tree> 
<four>4</four> 
+0

Нет, не имеет значения, последнее условие заканчивается текстовым контентом. - И нет, ваш код недействителен, потому что есть два закрывающих ']'. –

+0

благодарит за недопустимый комментарий. починил это. – lshaked

+0

Вы можете попробовать «* [not (self :: one or self :: two)] и не (normalize-space() = '')», помещая в конец предложения непустую, и вы получите пустой документ , – lshaked

Смежные вопросы