使用新标记将xml平面添加到层次结构xml

时间:2017-04-11 08:19:24

标签: xml xslt xslt-1.0

我有这个我需要设计风格的xml,但是甚至没有让for.each正常工作:我尝试为每个CONNECTIVITY_MESSAGE_LINE,如果NAME是'HEADER'那么......

我想要帮助开始...所以我至少可以使陈述正确,我已阅读并阅读......

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@* | node()"> 
    <xsl:element name="SEPA_HEADER">  
        <xsl:value-of select=". = HEADER"/>
        <xsl:if test="*//NAME[text() = 'HEADER']">
          <p>x</p>          
        </xsl:if>               
        <xsl:for-each select="CONNECTIVITY_MESSAGE/MESSAGE_LINE/CONNECTIVITY_MESSAGE_LINE">
          <P>1</P>
        <xsl:choose>
          <xsl:when test="//NAME[text() = 'HEADER']">
            <P>CHOOSE</P>
          </xsl:when>
          <xsl:otherwise>
            <p>123</p>
          </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>   
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>

我使用VS2013

我讨厌的xml:

<?xml version="1.0" encoding="UTF-8"?>
<CONNECTIVITY_MESSAGE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ifsworld-com:connectivity_message" ID="CONNECTIVITY_MESSAGE-6.0">
  <APPLICATION_MESSAGE_ID>N/A</APPLICATION_MESSAGE_ID>
  <APPLICATION_RECEIVER_ID>N/A</APPLICATION_RECEIVER_ID>
  <CLASS_ID>ISO20022</CLASS_ID>
  <CONNECTIVITY_VERSION>2.1.0</CONNECTIVITY_VERSION>
  <EXEC_TIME>2017-04-06T15:20:49</EXEC_TIME>
  <MEDIA_CODE>EDI</MEDIA_CODE>
  <OBJSTATE>Released</OBJSTATE>
  <RECEIVER>BANK</RECEIVER>
  <SENDER>IFS</SENDER>
  <STATE>Released</STATE>
  <VERSION>N/A</VERSION>
  <MESSAGE_LINES>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>ORDER_ID</C01>
      <C02>MESSAGE_ID</C02>
      <C03>CONTROL_SUM</C03>
      <C04>PURCHASENO</C04>
      <MESSAGE_LINE>1.0</MESSAGE_LINE>
      <NAME>HEADER</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P1</C01>
      <C02>line_rec_.Line_No</C02>
      <MESSAGE_LINE>2.0</MESSAGE_LINE>
      <NAME>PAYMENT</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P1</C01>
      <C02>T1.1</C02>
      <MESSAGE_LINE>3.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P1</C01>
      <C02>T1.2</C02>
      <MESSAGE_LINE>4.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P1</C01>
      <C02>T1.3</C02>
      <MESSAGE_LINE>5.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P2</C01>
      <C02>line_rec_.Line_No</C02>
      <MESSAGE_LINE>6.0</MESSAGE_LINE>
      <NAME>PAYMENT</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P2</C01>
      <C02>T2.1</C02>
      <MESSAGE_LINE>7.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P2</C01>
      <C02>T2.2</C02>
      <MESSAGE_LINE>8.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P3</C01>
      <C02>line_rec_.Line_No</C02>
      <MESSAGE_LINE>9.0</MESSAGE_LINE>
      <NAME>PAYMENT</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P3</C01>
      <C02>T3.1</C02>
      <MESSAGE_LINE>10.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P3</C01>
      <C02>T3.2</C02>
      <MESSAGE_LINE>11.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
    <CONNECTIVITY_MESSAGE_LINE>
      <C01>P3</C01>
      <C02>T3.3</C02>
      <MESSAGE_LINE>12.0</MESSAGE_LINE>
      <NAME>TRANS</NAME>
      <STATE>Posted</STATE>
    </CONNECTIVITY_MESSAGE_LINE>
  </MESSAGE_LINES>
</CONNECTIVITY_MESSAGE>

1 个答案:

答案 0 :(得分:0)

从您的帖子中不清楚您对输出XML的要求。对于处理输入XML的更多XSL-y方式,我建议如下。使用模板可以避免在您尝试使用模板的过程中对for-each的任何需求。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"

    exclude-result-prefixes="xs"
    version="2.0"

    xmlns="urn:ifsworld-com:connectivity_message"
    xpath-default-namespace="urn:ifsworld-com:connectivity_message">
    <!-- Note the `xpath-default-namespace` line here: this is only allowed in XSLT 2.0 and newer.
        The input XLIFF file itself specifies this URI as the unprefixed namespace for the whole file.
        If we don't specify this as the XPath default namespace, we have to specify element names
        in ugly workaround syntax, such as `*[local-name() = 'MESSAGE_LINES']`. -->

    <!-- Indent for easier human readability. -->
    <xsl:output method="xml" indent="yes"/>

    <!-- Strip space so that skipped elements don't result in blank whitespace in the output. -->
    <xsl:strip-space elements="*"/>

    <!-- Start at the top -->
    <xsl:template match="/CONNECTIVITY_MESSAGE">
        <!-- Here, we just copy the element.  Change if you need something different in your output. -->
        <xsl:copy>
            <!-- I assume here that you want to also copy over all of the elemnt attributes. -->
            <xsl:copy-of select="@*"/>
            <!-- Now, just pass in all the children elements for further processing. -->
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="MESSAGE_LINES">
        <!-- From your sample code, I have no clear idea if this is what 
            you intend for the SEPA_HEADER element.  Change as appropriate. -->
        <SEPA_HEADER>
            <!-- Now pass in all children of the MESSAGE_LINES element
                (in this case, all the CONNECTIVITY_MESSAGE_LINE structures).-->
            <xsl:apply-templates/>
        </SEPA_HEADER>
    </xsl:template>

    <xsl:template match="CONNECTIVITY_MESSAGE_LINE">
        <xsl:copy>
            <!-- Your sample code had:
                    <xsl:when test="//NAME[text() = 'HEADER']">
                The // here means that this is TRUE if there is *any* 
                NAME *anywhere in the file* that has text of 'HEADER'.
                Given your sample file, this will *always* be true, no
                matter where we are.  I suspect you instead need to 
                check if _this specific CONNECTIVITY_MESSAGE_LINE_ has
                a NAME element with text of 'HEADER'. -->
            <xsl:choose>
                <!-- You can test the text value of an element by simply evaluating `.` ("this").
                    You can, but you don't need to, evaluate using `text()`. -->
                <xsl:when test="NAME[. = 'HEADER']">
                    <p>CHOOSE</p>
                </xsl:when>
                <xsl:otherwise>
                    <p>123</p>
                </xsl:otherwise>
            </xsl:choose>
            <!-- I assume here that you want to copy all the children.
                Change as appropriate for your needs. -->
            <xsl:copy-of select="*"/>
        </xsl:copy>
    </xsl:template>

    <!-- Suppress output of anything else for which we do not have a specific template defined. -->
    <xsl:template match="*"/>

</xsl:stylesheet>

这应该让你开始。看一看,阅读评论,并告诉我们您可能还有哪些问题。