2012-04-04 60 views
1

我已經做了一些四處觀望,但是我沒有看到明顯的問題答案。我確定我忽略了一些東西,但我不知道是什麼。XSLT 2.0以特定值開頭的測試元素名稱

我已經對下面的XML進行了一些預處理以編輯一些元素名稱,並且在預處理之後,我有一個XSL樣式表進行簡單的標識轉換。但是,我想知道是否有辦法避免預處理步驟,並完成一個樣式表中的所有內容。兩個XML輸入之間的主要區別是<subj*>已變爲<subj>

是否有一種方法來測試元素名稱的開始(或結束,我也想)價值?非常感謝您的時間&建議。

我有XML輸入,看起來像這樣:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <row> 
     <issueNumber>1.001</issueNumber> 
     <subj1>Cats</subj1> 
     <subj2>LOLCats</subj2> 
     <subj3>Cheezburgers</subj3> 
     <subj4></subj4> 
    </row> 
    <row> 
     <issueNumber>2.001</issueNumber> 
     <subj1>Cats</subj1> 
     <subj2>LOLCats</subj2> 
     <subj3>NOMS</subj3> 
     <subj4>Cheezburger</subj4> 
    </row> 
    <row> 
     <issueNumber>3.001</issueNumber> 
     <subj1>NOMS</subj1> 
     <subj2></subj2> 
     <subj3></subj3> 
     <subj4></subj4> 
    </row> 
</root> 

我用下面的XSL處理它:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="2.0"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <xsl:apply-templates /> 
</xsl:template> 

<xsl:template match="row"> 
    <!--<xsl:result-document href="{concat(issueNumber, '.xml')}">--> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    <!--</xsl:result-document>-->  
</xsl:template> 

<xsl:template match="issueNumber"> 
    <xsl:copy> 
     <xsl:apply-templates /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="subj"> 
    <xsl:choose> 
     <xsl:when test="not(string(.))"></xsl:when> 
     <xsl:when test="string(.)"> 
      <subject> 
       <xsl:apply-templates /> 
      </subject> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

回答

1

如果我理解正確的問題,你可以做這樣的事情:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="*[starts-with(name(),'subj')]"> 
    <subj> 
     <xsl:if test="string(.)"> 
     <subject> 
      <xsl:apply-templates/> 
     </subject> 
     </xsl:if> 
    </subj> 
    </xsl:template> 

</xsl:stylesheet> 

使用您的XML輸入(修正得到很好的形成):

<root> 
    <row> 
    <issueNumber>1.001</issueNumber> 
    <subj1>Cats</subj1> 
    <subj2>LOLCats</subj2> 
    <subj3>Cheezburgers</subj3> 
    <subj4></subj4> 
    </row> 
    <row> 
    <issueNumber>2.001</issueNumber> 
    <subj1>Cats</subj1> 
    <subj2>LOLCats</subj2> 
    <subj3>NOMS</subj3> 
    <subj4>Cheezburger</subj4> 
    </row> 
    <row> 
    <issueNumber>3.001</issueNumber> 
    <subj1>NOMS</subj1> 
    <subj2></subj2> 
    <subj3></subj3> 
    <subj4></subj4> 
    </row> 
</root> 

產生下面的輸出:

<root> 
    <row> 
     <issueNumber>1.001</issueNumber> 
     <subj> 
     <subject>Cats</subject> 
     </subj> 
     <subj> 
     <subject>LOLCats</subject> 
     </subj> 
     <subj> 
     <subject>Cheezburgers</subject> 
     </subj> 
     <subj/> 
    </row> 
    <row> 
     <issueNumber>2.001</issueNumber> 
     <subj> 
     <subject>Cats</subject> 
     </subj> 
     <subj> 
     <subject>LOLCats</subject> 
     </subj> 
     <subj> 
     <subject>NOMS</subject> 
     </subj> 
     <subj> 
     <subject>Cheezburger</subject> 
     </subj> 
    </row> 
    <row> 
     <issueNumber>3.001</issueNumber> 
     <subj> 
     <subject>NOMS</subject> 
     </subj> 
     <subj/> 
     <subj/> 
     <subj/> 
    </row> 
</root> 
+0

我已經編輯了XML輸入 - 沒有足夠遠距離'' - 對此感到抱歉。你的樣式表最接近xsl:template match =「* [starts-with ...]」'的簡潔用法。非常感謝您的幫助! – CanOfBees 2012-04-04 20:11:12

+0

@CanOfBees - 非常歡迎! – 2012-04-05 01:28:55

2

您是否在尋找像 「正則表達式」在XSLT中?如果是的話,這個鏈接可能對你非常有用:http://www.w3.org/TR/xslt20/#regular-expressions

但是,這個解決方案只適用於XSLT 2.0。您可能會失去與舊版XSLT版本的兼容性。

+0

謝謝,多米尼克!問題不是正則表達式,而是在'xsl:template match =「...」'中正確使用'starts-with()'。 – CanOfBees 2012-04-04 20:05:13

+0

也 - 感謝您的規範鏈接 - 這是一個很好的提醒什麼是可用的。 – CanOfBees 2012-04-04 20:12:35

+0

年,規格常常是最好的參考。 – 2012-04-05 15:21:01

相關問題