0

我有一种情况,我有一个充满 xsd 文件的目录,需要对它们进行转换,为它们中的每一个生成一个输出文件。我的样式表在单个文档上运行良好,但我想扩展它。好吧,目前我还没有使用 xslt 编辑器,已经安装了 saxon。这是xslt文件:

<xsl:stylesheet version="1.0" 
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            >

<xsl:output method="text"/>

<!--* Ignore anything that looks complicated *-->
<xsl:template match="xsd:attribute 
                   | xsd:attributeGroup
                   | xsd:group
                   | xsd:schema/xsd:element[@type]
                   | xsd:notation
                   | xsd:annotation
                   "/>
<!--* Ignore text nodes (otherwise the output will be
  * inundated with whitespace) *-->

<xsl:template match="text()"/>

 <!--* Top-level elements with local complex types; those
  * we want to handle.
  *-->

<xsl:template match = "xsd:schema/xsd:element[xsd:complexType]">
<xsl:apply-templates/>
  </xsl:template>

  <!--* Aha!  A complex type whose content model we want to turn 
  * into a regular expression 
  *-->

<xsl:template match = "xsd:element/xsd:complexType
                     [xsd:sequence | xsd:choice | xsd:all]">
<!--* write out the name for the named regex *-->
<xsl:value-of select="concat('&#xA;&#xA;',
                      @name, parent::xsd:element/@name, 
                      ' ')"/>
<!--* write out the regex *-->
<xsl:apply-templates/>
</xsl:template>

<!--* Simple recursive case:  we encounter a model group. *-->

<xsl:template match = "xsd:sequence|xsd:choice|xsd:all">
<!--* Parenthesize the group and handle its children. *-->
<xsl:text>(</xsl:text>
<xsl:apply-templates/>
<xsl:text>)</xsl:text>

<!--* Append *, ?, +, or {min, max}. *-->
<xsl:call-template name="occurrence-indicator"/>

<!--* If our parent has further children, 
    * append the appropriate connector. *-->
<xsl:call-template name="connector"/>
</xsl:template>

<!--* An element in a content model. *-->
  <xsl:template match = "xsd:element[ancestor::xsd:complexType]">
<!--* Write out the element's name.  We're lazy so 
    * we don't bother with a QName for a local element.
    * Also, we don't recur. *-->
<xsl:value-of select="concat(@ref, @name)"/>

<!--* Handle occurrence indicator and connect
    * just as for groups. *-->
<xsl:call-template name="occurrence-indicator"/>
<xsl:call-template name="connector"/>
</xsl:template>


<!--* Emit the appropriate occurrence indicator for
  * a group or element.
  * Use {min,max}, {min,}, or {n} notation for 
  * non-standard occurrence counts.
  *-->

<xsl:template name="occurrence-indicator">
<xsl:choose>
  <xsl:when test="(@minOccurs='1' or not(@minOccurs)) 
                  and 
                  (@maxOccurs='1' or not(@maxOccurs))">
    <xsl:text></xsl:text>
  </xsl:when>
  <xsl:when test="@minOccurs='0' 
                  and 
                  (@maxOccurs='1' or not(@maxOccurs))">
    <xsl:text>?</xsl:text>
  </xsl:when>
  <xsl:when test="@minOccurs='0' and @maxOccurs='unbounded'">
    <xsl:text>*</xsl:text>
  </xsl:when>
  <xsl:when test="(@minOccurs='1' or not(@minOccurs)) 
                  and 
                  @maxOccurs='unbounded'">
    <xsl:text>+</xsl:text>
  </xsl:when>
  <xsl:when test="@minOccurs=@maxOccurs">
    <xsl:value-of select="concat('{', @minOccurs,'}')"/>
  </xsl:when>
  <xsl:when test="@maxOccurs='unbounded'">
    <xsl:value-of select="concat('{', @minOccurs,',}')"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="concat('{', 
                          @minOccurs,
                          ',',
                          @maxOccurs,
                          '}')"/>
  </xsl:otherwise>
</xsl:choose>
  </xsl:template>

  <xsl:template name="connector">
<!--* Emit the appropriate connector, if we need one. *-->
<xsl:if test="following-sibling::*[self::xsd:sequence 
              | self::xsd:choice 
              | self::xsd:all 
              | self::xsd:element]">
  <xsl:choose>
    <xsl:when test="parent::xsd:sequence">
      <xsl:text>, </xsl:text>
    </xsl:when>
    <xsl:when test="parent::xsd:choice">
      <xsl:text> | </xsl:text>
    </xsl:when>
    <xsl:when test="parent::xsd:all">
      <xsl:text> &amp; </xsl:text>
    </xsl:when>
  </xsl:choose>
</xsl:if>
  </xsl:template>

</xsl:stylesheet>
4

2 回答 2

2

There are so many ways to do match treatment (bash, vb-scrpt, ...).

I often use ant. Here some examples how to apply XSLT on multiple files in a folder. The ant "build.xml" file running the XSL transformation on all .xsd files in the "destinationFolder":

<?xml version="1.0" encoding="UTF-8"?>
<project name="TransformMultipleFiles" default="transformMulti">
   <property name="xsl_processor.file" value="saxon9he.jar"/>
   <target name="transformMulti">
    <!-- Transform all the files in the directory -->
       <xslt basedir="fileFolder" destdir="destinationFolder" includes="**/*.xsd" extension=".xml" style="yourXSLT.xslt" classpath="${xsl_processor.file}" />
   </target>
</project>

Just add above code into a file named build.xml and run the file with ant by just going into this directory and typing "ant" into the console. (ant must be installed of course - and the environment variables set). as ant is Java you can run it on any system: http://ant.apache.org/

Or you can use the collection() function, but I'm not sure if it works with all XSLT processors. See examples here: http://www.xmlplease.com/collection

于 2012-08-21T07:14:18.473 回答
0

如果您有权访问 bash shell,则可以这样做:导航到包含您要处理的文件的目录并键入

for schemadoc in *.xsd
  do echo "$schemadoc ..."
  xsltproc myxslt.xsl $schemadoc > $schemadoc.output.txt
done

这样做时,更改myxslt.xsl为您尝试运行的样式表的名称,并更改开头的行xsltproc以匹配从命令行调用 XSLT 处理器的正确方法。

或者,如果您可以访问 Oxygen,则可以阅读如何将样式表应用于给定目录中的所有文件(或所有 *.xsd 文件),然后按照这种方式进行操作。

或者,如果您无法访问其中任何一个,请找一个在您发现自己所在的计算环境中成功且愉快地工作的人,并询问他们将如何做到这一点。

在一组文件上运行一个进程是一项基本技能,并且有很多很多方法可以做到这一点。它与 XSLT 样式表的具体内容完全没有关系,而且从根本上说,它不是一个 XSLT 问题,除非出于某种原因它必须在单个 XSLT 进程中完成(在这种情况下,请仔细听 Dimitre Novatchev 所说的任何内容) . 找到一种、三种或五十五种适用于你的环境的方法并学习它们。

于 2012-08-21T17:11:16.673 回答