2012-07-03 4 views
2

У меня есть рабочий процесс XML, в котором мы строим выходной документ из источника XML, но некоторые элементы данных пустые, но все еще появляются на выходе. Проблема в том, что мы генерируем возврат параграфа и интервал на основе конечного результата.Игнорирование пустых элементов с помощью XSL

В некоторых случаях данные содержат <address1> и <address2> элементы. Когда это делает, мы хотим, чтобы выглядеть следующим образом (A):

<address1>123 Main Str</address1><xsl:text> </xsl:text><zip>60060</zip> 

Когда нет данных в <address2> элемента, мы хотим, чтобы выглядеть так (B):

<address1>123 Main Str</address1> <hours>M-F 9:00am - 5:00pm</hours><xsl:text> 
</xsl:text><address2>PO Box 123</address2> <zip>60060</zip> 

НО , то XML содержит элементы пУСТЫЕ данных, таких как <address2></address2> поэтому мы в конечном итоге со следующей ситуацией (C):

<address1>123 Main Str</address1> <hours>M-F 9:00am - 5:00pm</hours><xsl:text> 
</xsl:text><address2/><xsl:text> </xsl:text><zip>60060</zip> 

Наш XSL работает отлично до тех пор, пока не натыкается на пустой элемент. Я уверен, что есть способ создать вариант A, даже если есть пустой элемент. Я попытался использовать <xsl:if test="string-length(node) != 0">, но я не мог заставить его работать. Я хочу избавиться от пустых элементов <address2/> и переместить элемент <zip> до предыдущей строки.

Вот мой текущий XSL:

<?xml version="1.0" encoding="UTF-8"?><!-- DWXMLSource="IndividualBanks_2011 final.xml" --> 
<!DOCTYPE xsl:stylesheet> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:strip-space elements="*"/> 

<xsl:output method="xml"/> 
<xsl:template match="/"> 

<Root> 
<Story><xsl:apply-templates select="Root"/></Story> 
</Root> 
</xsl:template> 

<xsl:template match="BankName | Address1 | Hours | Established | RoutingNbr | CO/CityOfficePhone | CO/CityOfficeAddress2 "><xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element></xsl:template> 
<xsl:template match="BK"> 
<xsl:apply-templates select="BankName"/><xsl:text> </xsl:text><xsl:apply-templates select="Established"/> <xsl:text> </xsl:text><xsl:apply-templates select="RoutingNbr"/><xsl:text> 
</xsl:text> 
<xsl:apply-templates select="OfficeOfLabel"/> 
<xsl:apply-templates select="Address1"/><xsl:text> </xsl:text><xsl:apply-templates select="Hours"/> 
<xsl:apply-templates select="Address2"/><xsl:apply-templates select="Zip"/> 
</xsl:template> 
<xsl:template match="Address2"><xsl:text> 
</xsl:text><Address2><xsl:value-of select="."/></Address2><xsl:text> </xsl:text> 
</xsl:template> 

<xsl:template match="Zip"> 
<Zip><xsl:value-of select="."/></Zip><xsl:text> 
</xsl:text></xsl:template> 
</xsl:stylesheet> 

Вот источник данных XML:

<Root><BK><BankName>Ames National Corporation</BankName><Established>Est. 1975</Established><RoutingNbr>8020-0135-0</RoutingNbr><Address1>405 5th Street</Address1><Hours>Hrs: M-F 8-5</Hours><Address2></Address2> <Zip>50010</Zip><Fax>FAX: (515) 663-3033</Fax><Phone>(515) 232-6251</Phone><WebURL>Web: www.amesnational.com</WebURL><MultiBankLabel>Please see Multi-Bank Holding Companies section</MultiBankLabel> 
</BK> 
<BK><BankName>Bank of the West</BankName><Address1>525 Main</Address1><Zip>50010-6008</Zip><Fax>FAX: (515) 232-3791</Fax><Phone>(515) 232-8664</Phone><OfficeOfLabel>Office of Bank of the West, West Des Moines</OfficeOfLabel> 
<EH><Employee>Michael Sondall, BM</Employee></EH> 
</BK> 
<BK><BankName>Bankers Trust Company</BankName><Address1>1510 Buckeye </Address1><Zip>50010</Zip><Phone>(515) 233-4424</Phone><WebURL>Web: www.bankerstrust.com</WebURL><OfficeOfLabel>Office of Bankers Trust Company, Des Moines</OfficeOfLabel> 
<EH><Employee>John Russell, VP</Employee></EH> 
</BK> 
<BK><BankName>Exchange State Bank</BankName><RoutingNbr>0739-0950-7</RoutingNbr><Address1>823 Wheeler, Ste 32</Address1><Zip>50010</Zip><Fax>FAX: (515) 232-5068</Fax><Phone>(515) 232-5060</Phone><Email>e-Mail: [email protected]</Email><OfficeOfLabel>Office of Exchange State Bank, Collins</OfficeOfLabel> 
<EH><Employee>Allison Appel, VP, CPA</Employee></EH><EH><Employee>Christine Heintz, AVP</Employee></EH> 
</BK> 
<BK><BankName>First American Bank</BankName><Established>Est. 1956</Established><RoutingNbr>0739-0080-7</RoutingNbr><Address1>1530 S Duff Avenue, Ste 1</Address1><Hours>Hrs: M-TH 9-5 SAT 8-12</Hours><Address2> </Address2><Zip>50010</Zip><Fax>FAX: (515) 956-3160</Fax><Phone>(515) 233-2033</Phone><WebURL>Web: </WebURL> <OfficeOfLabel>Office of First American Bank, Fort Dodge</OfficeOfLabel> 
<EH><Employee>Steve Goodhue, Reg Pres</Employee></EH> 
</BK></Root> 
+0

Просто интересно - являются (A) и (B) поменяны местами? Кроме того, ваш XML-источник данных не является корректным (должен заканчиваться на '', а не ''). –

+0

Кроме того, я не уверен, почему для вас результат с пустыми элементами '' включает элементы '' - это не для меня. Пожалуйста, позаботьтесь о надлежащем корпусе.Xml чувствителен к регистру, поэтому '' (как в ваших фрагментах кода) не совпадает с '' (как в ваших полных документах Xml). –

+0

Извините за небольшие ошибки, я извлек XML из более крупного файла для простоты и добавил родительские теги назад и ввел некоторые опечатки. Фактический XML хорошо сформирован. –

ответ

0

Ваш подход с функцией string-length не было плохо, но, возможно, вы вставили его в заблуждении место?

<Zip> элемент на предыдущей строке для меня, когда я заменить ваш XSLT линия

<xsl:template match="Address2"><xsl:text> 

с

<xsl:template match="Address2[string-length() != 0]"><xsl:text> 

ли делать то, что вы хотите? Я не совсем уверен, хотите ли вы пропустить <Hours>, если нет <Address2>.

Update: Чтобы применить другой порядок к элементам, если <Address2> пуст, используйте <xsl:choose> структуру с аналогичным условием, как указано выше:

<xsl:template match="BK"> 
<xsl:apply-templates select="BankName"/><xsl:text> </xsl:text><xsl:apply-templates select="Established"/> <xsl:text> </xsl:text><xsl:apply-templates select="RoutingNbr"/><xsl:text> 
</xsl:text> 
<xsl:apply-templates select="OfficeOfLabel"/> 
<xsl:choose> 
<xsl:when test="string-length(Address2) != 0"> 
<xsl:apply-templates select="Address1"/><xsl:text> </xsl:text><xsl:apply-templates select="Hours"/> 
<xsl:apply-templates select="Address2"/><xsl:apply-templates select="Zip"/> 
</xsl:when> 
<xsl:otherwise> 
<xsl:apply-templates select="Address1"/><xsl:text> </xsl:text><xsl:apply-templates select="Zip"/><xsl:text> </xsl:text><xsl:apply-templates select="Hours"/> 
</xsl:otherwise> 
</xsl:choose> 
</xsl:template> 

Вы можете полностью пропустить шаблон для <Address2> ,

+0

Это работало как чемпион. Отлично. Это как они говорят о ресторанах, местоположении, местонахождении, местонахождении .... По смежной теме мой босс хочет, чтобы zip появлялся BETWEEN '' и '', если элемент '' пуст. Любые предложения о том, как мы настроили это условие? Прямо сейчас, появляется ПОСЛЕ ''. –

+0

@JimMaivald: в шаблоне, начинающемся с '', вы вставляете различные элементы (с помощью 'xsl: apply-templates > ') в фиксированном порядке. Одним из этих элементов является элемент ''. Попытайтесь использовать '' или '' там, чтобы проверить, является ли '' пустым, и если да, вставьте элементы в другом порядке. Дайте мне знать, если эта информация недостаточна. –

+0

Мне никогда не повезло с функцией xsl: if. Я могу создать один шаблон, если адрес2 есть, а затем вставить другой, если адрес 2 отсутствует в разделе «в противном случае»? Также следует оставить элементы '' и '' из раздела «соответствие», отмеченного выше, если они указаны в инструкции «xsl: if»? –

1

Там, кажется, многочисленные несоответствия в информации, которую вы нам оказали, но простое решение, чтобы добавить правило шаблона:

<xsl:template match="address2[not(child::node())]"/> 
+0

Извините за небольшие ошибки. XML был на самом деле хорошо сформирован, но я добавил только его часть, чтобы сэкономить место. Спасибо за ответ –